1  /-
  2  Copyright (c) 2017 Johannes Hölzl. All rights reserved.
  3  Released under Apache 2.0 license as described in the file LICENSE.
  4  Author: Mario Carneiro
  5  
  6  Ordinal arithmetic.
  7  
  8  Ordinals are defined as equivalences of well-ordered sets by order isomorphism.
  9  -/
 10  import order.order_iso set_theory.cardinal data.sum
src         └─────────────┘ └─────────────────┘ └──────┘
 11  noncomputable theory
 12  
 13  open function cardinal set equiv
 14  open_locale classical cardinal
 15  
 16  universes u v w
 17  variables {α : Type*} {β : Type*} {γ : Type*}
 18    {r : α → α → Prop} {s : β → β → Prop} {t : γ → γ → Prop}
 19  
 20  /-- If `r` is a relation on `α` and `s` in a relation on `β`, then `f : r ≼i s` is an order embedding whose range is an initial segment. That is, whenever `b < f a` in `β` then `b` is in the range of `f`. -/
 21  structure initial_seg {α β : Type*} (r : α → α → Prop) (s : β → β → Prop) extends r ≼o s :=
id                                └───┘                                           └┘ 
src                                                                                      └┘
typ                               └───┘                                           └┘ 
doc                                                                                      └┘
 22  (init : ∀ a b, s b (to_order_embedding a) → ∃ a', to_order_embedding a' = b)
id                   └────────────────┘      └┘ └────────────────┘ └┘  
src                                                                        
typ                  └────────────────┘      └┘ └────────────────┘ └┘  
 23  
 24  local infix ` ≼i `:25 := initial_seg
id                            └─────────┘
src                           └─────────┘
typ                           └─────────┘
doc                           └─────────┘
 25  
 26  namespace initial_seg
 27  
 28  instance : has_coe (r ≼i s) (r ≼o s) := ⟨initial_seg.to_order_embedding⟩
id              └─────┘   └┘     └┘       └────────────────────────────┘
src             └─────┘    └┘       └┘        └────────────────────────────┘
typ             └─────┘   └┘     └┘       └────────────────────────────┘
doc                        └┘       └┘
 29  
 30  @[simp] theorem coe_fn_mk (f : r ≼o s) (o) :
id                                   └┘ 
src                                   └┘
typ                                  └┘ 
doc    └──┘                           └┘
 31    (@initial_seg.mk _ _ r s f o : α → β) = f := rfl
id       └────────────┘                     └─┘
src      └────────────┘                            └─┘
typ      └────────────┘                     └─┘
 32  
 33  @[simp] theorem coe_fn_to_order_embedding (f : r ≼i s) : (f.to_order_embedding : α → β) = f := rfl
id                                                   └┘      └─────────────────┘             └─┘
src                                                   └┘        └─────────────────┘                └─┘
typ                                                  └┘      └─────────────────┘             └─┘
doc    └──┘                                           └┘
 34  
 35  theorem coe_coe_fn (f : r ≼i s) : ((f : r ≼o s) : α → β) = f := rfl
id                            └┘           └┘               └─┘
src                            └┘              └┘                   └─┘
typ                           └┘           └┘               └─┘
doc                            └┘              └┘
 36  
 37  theorem init' (f : r ≼i s) {a : α} {b : β} : s b (f a) → ∃ a', f a' = b :=
id                       └┘                            └┘  └┘  
src                       └┘                                           
typ                      └┘                            └┘  └┘  
doc                       └┘
 38  f.init _ _
id   └───┘
src   └───┘
typ  └───┘
 39  
 40  theorem init_iff (f : r ≼i s) {a : α} {b : β} : s b (f a) ↔ ∃ a', f a' = b ∧ r a' a :=
id                          └┘                           └┘  └┘     └┘ 
src                          └┘                                             
typ                         └┘                           └┘  └┘     └┘ 
doc                          └┘
 41  ⟨λ h, let ⟨a', e⟩ := f.init' h in ⟨a', e, (f : r ≼o s).ord'.2 (e.symm ▸ h)⟩,
id        └─┘  └┘       └────┘                  └┘  └──┘     └───┘  
src                        └────┘                     └┘   └──┘     └───┘ 
typ       └─┘  └┘       └────┘                  └┘  └──┘     └───┘  
doc                                                   └┘
 42   λ ⟨a', e, h⟩, e ▸ (f : r ≼o s).ord'.1 h⟩
id                       └┘  └──┘ 
src                           └┘   └──┘ 
typ                      └┘  └──┘ 
doc                            └┘
 43  
 44  /-- An order isomorphism is an initial segment -/
 45  def of_iso (f : r ≃o s) : r ≼i s :=
id                    └┘      └┘ 
src                    └┘        └┘
typ                   └┘      └┘ 
doc                    └┘        └┘
 46  ⟨f, λ a b h, ⟨f.symm b, order_iso.apply_symm_apply f _⟩⟩
id             └───┘   └────────────────────────┘ 
src                 └───┘    └────────────────────────┘
typ            └───┘   └────────────────────────┘ 
 47  
 48  /-- The identity function shows that `≼i` is reflexive -/
 49  @[refl] protected def refl (r : α → α → Prop) : r ≼i r :=
id                                                  └┘ 
src    └──┘                                            └┘
typ                                                 └┘ 
doc    └──┘                                            └┘
 50  ⟨order_embedding.refl _, λ a b h, ⟨_, rfl⟩⟩
id    └──────────────────┘              └─┘
src   └──────────────────┘                 └─┘
typ   └──────────────────┘              └─┘
 51  
 52  /-- Composition of functions shows that `≼i` is transitive -/
 53  @[trans] protected def trans (f : r ≼i s) (g : s ≼i t) : r ≼i t :=
id                                      └┘         └┘      └┘ 
src    └───┘                             └┘           └┘        └┘
typ                                     └┘         └┘      └┘ 
doc    └───┘                             └┘           └┘        └┘
 54  ⟨f.1.trans g.1, λ a c h, begin
id     └───┘         
src     └───┘   
typ    └───┘         
st                            └─────
 55    simp at h ⊢,
src    └─────────┘
typ    └─────────┘
doc    └─────────┘
txt    └─────────┘
par    └─────────┘
pid        └────┘
st   ────────────┘└─
 56    rcases g.2 _ _ h with ⟨b, rfl⟩, have h := g.1.ord'.2 h,
id                                                       
src    └─────┘ └─────┘ └────────────┘  └────────┘ └────────┘
typ    └─────┘└─────┘└────────────┘  └────────┘└────────┘
doc    └─────┘ └─────┘ └────────────┘  └────────┘ └────────┘
txt    └─────┘ └─────┘ └────────────┘  └────────┘ └────────┘
par    └─────┘ └─────┘ └────────────┘  └────────┘ └────────┘
pid           └─────┘ └────────────┘  └────┘└─┘ └────────┘
st   ───────────────────────────────┘└──────────────────────┘└─
 57    rcases f.2 _ _ h with ⟨a', rfl⟩, exact ⟨a', rfl⟩
id                                           └┘  └─┘
src    └─────┘ └─────┘ └─────────────┘  └────┘   └┘└─┘└┘
typ    └─────┘└─────┘└─────────────┘  └────┘ └┘└┘└─┘└┘
doc    └─────┘ └─────┘ └─────────────┘  └────┘   └┘   └┘
txt    └─────┘ └─────┘ └─────────────┘  └────┘   └┘   └┘
par    └─────┘ └─────┘ └─────────────┘  └────┘   └┘   └┘
pid           └─────┘ └─────────────┘          └┘   
st   ────────────────────────────────┘└────────────────┘
 58  end⟩
st   └─┘
 59  
 60  @[simp] theorem of_iso_apply (f : r ≃o s) (x : α) : of_iso f x = f x := rfl
id                                      └┘            └────┘         └─┘
src                                      └┘              └────┘             └─┘
typ                                     └┘            └────┘         └─┘
doc    └──┘                              └┘              └────┘
 61  
 62  @[simp] theorem refl_apply (x : α) : initial_seg.refl r x = x := rfl
id                                       └──────────────┘        └─┘
src                                       └──────────────┘           └─┘
typ                                      └──────────────┘        └─┘
doc    └──┘                               └──────────────┘
 63  
 64  @[simp] theorem trans_apply (f : r ≼i s) (g : s ≼i t) (a : α) : (f.trans g) a = g (f a) := rfl
id                                     └┘         └┘             └────┘             └─┘
src                                     └┘           └┘                └────┘                  └─┘
typ                                    └┘         └┘             └────┘             └─┘
doc    └──┘                             └┘           └┘                └────┘
 65  
 66  theorem unique_of_extensional [is_extensional β s] :
id                                  └────────────┘  
src                                 └────────────┘
typ                                 └────────────┘  
doc                                 └────────────┘
 67    well_founded r → subsingleton (r ≼i s) | ⟨h⟩ :=
id     └──────────┘   └──────────┘   └┘ 
src    └──────────┘     └──────────┘    └┘
typ    └──────────┘   └──────────┘   └┘ 
doc                                     └┘
 68  ⟨λ f g, begin
id       
typ      
st           └─────
 69    suffices : (f : α → β) = g, { cases f, cases g,
id                                            
src    └─────────┘  └─┘   └┘     └────┘   └────┘
typ    └─────────┘ └─┘ └┘    └────┘  └────┘
doc    └─────────┘  └─┘   └┘      └────┘   └────┘
txt    └─────────┘  └─┘   └┘      └────┘   └────┘
par    └─────────┘  └─┘   └┘      └────┘   └────┘
pid    └───────┘└┘  └─┘   └┘                   
st   ───────────────────────────┘└──┘└─────┘└───────┘└─
 70      congr, exact order_embedding.eq_of_to_fun_eq this },
id                    └─────────────────────────────┘ └──┘
src      └───┘  └────┘└─────────────────────────────┘    
typ      └───┘  └────┘└─────────────────────────────┘└──┘
doc             └────┘                                   
txt      └───┘  └────┘                                   
par      └───┘  └────┘                                   
pid                                                     
st   ────────┘└───────────────────────────────────────────┘└┘
 71    funext a, have := h a, induction this with a H IH,
id                                    └──┘
src    └──────┘  └──────┘    └────────┘    └──────────┘
typ    └──────┘  └──────┘  └────────┘└──┘└──────────┘
doc    └──────┘  └──────┘    └────────┘    └──────────┘
txt    └──────┘  └──────┘    └────────┘    └──────────┘
par    └──────┘  └──────┘    └────────┘    └──────────┘
pid          └┘  └───┘└─┘                 └─────────┘
st   ─────────┘└───────────┘└──────────────────────────┘└─
 72    refine @is_extensional.ext _ s _ _ _ (λ x, ⟨λ h, _, λ h, _⟩),
id             └────────────────┘   
src    └─────┘ └────────────────┘└─┘ └─────┘  └──┘  └─────┘ └─────┘
typ    └─────┘ └────────────────┘└─┘└─────┘  └──┘  └─────┘ └─────┘
doc    └─────┘                   └─┘ └─────┘  └──┘  └─────┘ └─────┘
txt    └─────┘                   └─┘ └─────┘  └──┘  └─────┘ └─────┘
par    └─────┘                   └─┘ └─────┘  └──┘  └─────┘ └─────┘
pid                             └─┘ └─────┘  └──┘  └─────┘ └─────┘
st   ─────────────────────────────────────────────────────────────┘└─
 73    { rcases f.init_iff.1 h with ⟨y, rfl, h'⟩,
id              └────────┘   
src      └─────┘└────────┘└─┘ └────────────────┘
typ      └─────┘└────────┘└─┘└────────────────┘
doc      └─────┘          └─┘ └────────────────┘
txt      └─────┘          └─┘ └────────────────┘
par      └─────┘          └─┘ └────────────────┘
pid                      └─┘ └────────────────┘
st   ───┘└─────────────────────────────────────┘└─
 74      rw IH _ h', exact (g : r ≼o s).ord'.1 h' },
id          └┘   └┘             └┘          └┘
src      └─┘  └─┘    └────┘  └─┘ └┘ └───────┘  
typ      └─┘└┘└─┘└┘  └────┘ └─┘└┘└───────┘└┘
doc      └─┘  └─┘    └────┘  └─┘ └┘ └───────┘  
txt      └─┘  └─┘    └────┘  └─┘    └───────┘  
par      └─┘  └─┘    └────┘  └─┘    └───────┘  
pid          └─┘           └─┘    └───────┘  
st   ─────────────┘└─────────────────────────────┘└┘
 75    { rcases g.init_iff.1 h with ⟨y, rfl, h'⟩,
id              └────────┘   
src      └─────┘└────────┘└─┘ └────────────────┘
typ      └─────┘└────────┘└─┘└────────────────┘
doc      └─────┘          └─┘ └────────────────┘
txt      └─────┘          └─┘ └────────────────┘
par      └─────┘          └─┘ └────────────────┘
pid                      └─┘ └────────────────┘
st   ──────────────────────────────────────────┘└─
 76      rw ← IH _ h', exact (f : r ≼o s).ord'.1 h' }
id            └┘   └┘                         └┘
src      └───┘  └─┘    └────┘  └─┘    └───────┘  
typ      └───┘└┘└─┘└┘  └────┘ └─┘  └───────┘└┘
doc      └───┘  └─┘    └────┘  └─┘    └───────┘  
txt      └───┘  └─┘    └────┘  └─┘    └───────┘  
par      └───┘  └─┘    └────┘  └─┘    └───────┘  
pid        └─┘  └─┘           └─┘    └───────┘  
st   ───────────────┘└─────────────────────────────┘└─
 77  end⟩
st   ──┘
 78  
 79  instance [is_well_order β s] : subsingleton (r ≼i s) :=
id             └───────────┘      └──────────┘   └┘ 
src            └───────────┘        └──────────┘    └┘
typ            └───────────┘      └──────────┘   └┘ 
doc            └───────────┘                        └┘
 80  ⟨λ a, @subsingleton.elim _ (unique_of_extensional
id         └───────────────┘    └───────────────────┘
src         └───────────────┘    └───────────────────┘
typ        └───────────────┘    └───────────────────┘
 81    (@order_embedding.well_founded _ _ r s a (is_well_order.wf s))) a⟩
id       └──────────────────────────┘         └──────────────┘     
src      └──────────────────────────┘            └──────────────┘
typ      └──────────────────────────┘         └──────────────┘     
 82  
 83  protected theorem eq [is_well_order β s] (f g : r ≼i s) (a) : f a = g a :=
id                         └───────────┘            └┘             
src                        └───────────┘               └┘              
typ                        └───────────┘            └┘             
doc                        └───────────┘               └┘
 84  by rw subsingleton.elim f g
id         └───────────────┘  
src     └─┘└───────────────┘  
typ     └─┘└───────────────┘
doc     └─┘                   
txt     └─┘                   
par     └─┘                   
pid                          
st     └─────────────────────────
 85  
src  
typ  
doc  
txt  
par  
pid  
st   
 86  theorem antisymm.aux [is_well_order α r] (f : r ≼i s) (g : s ≼i r) : left_inverse g f :=
id                         └───────────┘          └┘         └┘     └──────────┘  
src                        └───────────┘             └┘           └┘      └──────────┘
typ                        └───────────┘          └┘         └┘     └──────────┘  
doc                        └───────────┘             └┘           └┘
 87  initial_seg.eq (f.trans g) (initial_seg.refl _)
id   └────────────┘  └────┘    └──────────────┘
src  └────────────┘   └────┘     └──────────────┘
typ  └────────────┘  └────┘    └──────────────┘
doc                   └────┘     └──────────────┘
 88  
 89  /-- If we have order embeddings between `α` and `β` whose images are initial segments, and β is a well-order then `α` and `β` are order-isomorphic. -/
 90  def antisymm [is_well_order β s] (f : r ≼i s) (g : s ≼i r) : r ≃o s :=
id                 └───────────┘          └┘         └┘      └┘ 
src                └───────────┘             └┘           └┘        └┘
typ                └───────────┘          └┘         └┘      └┘ 
doc                └───────────┘             └┘           └┘        └┘
 91  by haveI := f.to_order_embedding.is_well_order; exact
id               └────────────────────────────────┘
src     └───────┘└────────────────────────────────┘  └────┘
typ     └───────┘└────────────────────────────────┘  └────┘
doc     └───────┘                                    └────┘
txt     └───────┘                                    └────┘
par     └───────┘                                    └────┘
pid          └─┘                                         
st     └───────────────────────────────────────────────────
 92  ⟨⟨f, g, antisymm.aux f g, antisymm.aux g f⟩, f.ord⟩
id                             └──────────┘      └───┘
src     └┘ └┘              └┘└──────────┘  └─┘└───┘└─
typ     └┘ └┘              └┘└──────────┘ └─┘└───┘└─
doc     └┘ └┘              └┘              └─┘     └─
txt     └┘ └┘              └┘              └─┘     └─
par     └┘ └┘              └┘              └─┘     └─
pid     └┘ └┘              └┘              └─┘     
st   ────────────────────────────────────────────────────
 93  
src  
typ  
doc  
txt  
par  
pid  
st   
 94  @[simp] theorem antisymm_to_fun [is_well_order β s]
id                                    └───────────┘  
src                                   └───────────┘
typ                                   └───────────┘  
doc    └──┘                           └───────────┘
 95    (f : r ≼i s) (g : s ≼i r) : (antisymm f g : α → β) = f := rfl
id           └┘         └┘      └──────┘               └─┘
src           └┘           └┘       └──────┘                    └─┘
typ          └┘         └┘      └──────┘               └─┘
doc           └┘           └┘       └──────┘
 96  
 97  @[simp] theorem antisymm_symm [is_well_order α r] [is_well_order β s]
id                                  └───────────┘     └───────────┘  
src                                 └───────────┘       └───────────┘
typ                                 └───────────┘     └───────────┘  
doc    └──┘                         └───────────┘       └───────────┘
 98    (f : r ≼i s) (g : s ≼i r) : (antisymm f g).symm = antisymm g f :=
id           └┘         └┘      └──────┘   └──┘   └──────┘  
src           └┘           └┘       └──────┘     └──┘   └──────┘
typ          └┘         └┘      └──────┘   └──┘   └──────┘  
doc           └┘           └┘       └──────┘             └──────┘
 99  order_iso.eq_of_to_fun_eq rfl
id   └───────────────────────┘ └─┘
src  └───────────────────────┘ └─┘
typ  └───────────────────────┘ └─┘
100  
101  theorem eq_or_principal [is_well_order β s] (f : r ≼i s) : surjective f ∨ ∃ b, ∀ x, s x b ↔ ∃ y, f y = x :=
id                            └───────────┘          └┘     └────────┘                  
src                           └───────────┘             └┘      └────────┘                          
typ                           └───────────┘          └┘     └────────┘                  
doc                           └───────────┘             └┘
102  or_iff_not_imp_right.2 $ λ h b,
id   └──────────────────┘       
src  └──────────────────┘
typ  └──────────────────┘       
103  acc.rec_on ((is_well_order.wf s).apply b) $ λ x H IH,
id   └────────┘   └──────────────┘  └───┘          └┘
src  └────────┘   └──────────────┘   └───┘
typ  └────────┘   └──────────────┘  └───┘          └┘
104  not_forall_not.1 $ λ hn,
id   └────────────┘      └┘
src  └────────────┘
typ  └────────────┘      └┘
105  h ⟨x, λ y, ⟨(IH _), λ ⟨a, e⟩, by rw ← e; exact
id             └┘                      
src                                   └───┘   └─────
typ            └┘                 └───┘  └─────
doc                                   └───┘   └─────
txt                                   └───┘   └─────
par                                   └───┘   └─────
pid                                     └─┘        
st                                  └──────────────
106    (trichotomous _ _).resolve_right
id      └──────────┘
src  ─┘ └──────────┘└───────────────────
typ  ─┘ └──────────┘└───────────────────
doc  ─┘             └───────────────────
txt  ─┘             └───────────────────
par  ─┘             └───────────────────
pid  ─┘             └───────────────────
st   ───────────────────────────────────
107    (not_or (hn a) (λ hl, not_exists.2 hn (f.init' hl)))⟩⟩
id      └────┘              └────────┘   └┘  └─────┘
src  ─┘ └────┘    └┘  └───┘└────────┘└─┘   └─────┘  └─┘
typ  ─┘ └────┘   └┘  └───┘└────────┘└─┘└┘ └─────┘  └─┘
doc  ─┘           └┘  └───┘          └─┘            └─┘
txt  ─┘           └┘  └───┘          └─┘            └─┘
par  ─┘           └┘  └───┘          └─┘            └─┘
pid  ─┘           └┘  └───┘          └─┘            └─┘
st   ─────────────────────────────────────────────────────┘
108  
109  /-- Restrict the codomain of an initial segment -/
110  def cod_restrict (p : set β) (f : r ≼i s) (H : ∀ a, f a ∈ p) : r ≼i subrel s p :=
id                         └─┘         └┘                    └┘ └────┘  
src                        └─┘           └┘                          └┘ └────┘
typ                        └─┘         └┘                    └┘ └────┘  
doc                                      └┘                           └┘ └────┘
111  ⟨order_embedding.cod_restrict p f H, λ a ⟨b, m⟩ (h : s b (f a)),
id    └──────────────────────────┘                       
src   └──────────────────────────┘
typ   └──────────────────────────┘                       
doc   └──────────────────────────┘
112    let ⟨a', e⟩ := f.init' h in ⟨a', by clear _let_match; subst e; refl⟩⟩
id     └─┘  └┘        └────┘                                     
src                    └────┘              └──────────────┘  └────┘   └──┘
typ    └─┘  └┘        └────┘             └──────────────┘  └────┘  └──┘
doc                                        └──────────────┘  └────┘   └──┘
txt                                        └──────────────┘  └────┘   └──┘
par                                        └──────────────┘  └────┘   └──┘
pid                                             └─────────┘       
st                                        └──────────────────────────────┘
113  
114  @[simp] theorem cod_restrict_apply (p) (f : r ≼i s) (H a) : cod_restrict p f H a = ⟨f a, H a⟩ := rfl
id                                                └┘           └──────────┘                └─┘
src                                                └┘            └──────────┘                        └─┘
typ                                               └┘           └──────────┘                └─┘
doc    └──┘                                        └┘            └──────────┘
115  
116  def le_add (r : α → α → Prop) (s : β → β → Prop) : r ≼i sum.lex r s :=
id                                                   └┘ └─────┘  
src                                                       └┘ └─────┘
typ                                                  └┘ └─────┘  
doc                                                       └┘ └─────┘
117  ⟨⟨⟨sum.inl, λ _ _, sum.inl.inj⟩, λ a b, sum.lex_inl_inl.symm⟩,
id      └─────┘       └─────────┘        └─────────────┘└───┘
src     └─────┘         └─────────┘          └─────────────┘└───┘
typ     └─────┘       └─────────┘        └─────────────┘└───┘
118    λ a b, by cases b; [exact λ _, ⟨_, rfl⟩, exact false.elim ∘ sum.lex_inr_inl]⟩
id                                    └─┘         └────────┘  └─────────────┘
src              └────┘   └────┘ └──┘ └─┘└─┘  └────┘└────────┘└─────────────┘
typ            └────┘  └────┘ └──┘ └─┘└─┘  └────┘└────────┘└─────────────┘
doc              └────┘    └────┘ └──┘ └─┘     └────┘           
txt              └────┘    └────┘ └──┘ └─┘     └────┘           
par              └────┘    └────┘ └──┘ └─┘     └────┘           
pid                             └──┘ └─┘                     
st              └─────────────────────────────────────────────────────────────────┘
119  
120  @[simp] theorem le_add_apply (r : α → α → Prop) (s : β → β → Prop)
id                                                         
typ                                                        
doc    └──┘
121    (a) : le_add r s a = sum.inl a := rfl
id           └────┘     └─────┘     └─┘
src          └────┘        └─────┘      └─┘
typ          └────┘     └─────┘     └─┘
122  
123  end initial_seg
124  
125  structure principal_seg {α β : Type*} (r : α → α → Prop) (s : β → β → Prop) extends r ≼o s :=
id                                  └───┘                                           └┘ 
src                                                                                        └┘
typ                                 └───┘                                           └┘ 
doc                                                                                        └┘
126  (top : β)
id          
typ         
127  (down : ∀ b, s b top ↔ ∃ a, to_order_embedding a = b)
id                 └─┘    └────────────────┘   
src                                                
typ                └─┘    └────────────────┘   
128  
129  local infix ` ≺i `:25 := principal_seg
id                            └───────────┘
src                           └───────────┘
typ                           └───────────┘
130  
131  namespace principal_seg
132  
133  instance : has_coe (r ≺i s) (r ≼o s) := ⟨principal_seg.to_order_embedding⟩
id              └─────┘   └┘     └┘       └──────────────────────────────┘
src             └─────┘    └┘       └┘        └──────────────────────────────┘
typ             └─────┘   └┘     └┘       └──────────────────────────────┘
doc                                 └┘
134  
135  @[simp] theorem coe_fn_mk (f : r ≼o s) (t o) :
id                                   └┘ 
src                                   └┘
typ                                  └┘ 
doc    └──┘                           └┘
136    (@principal_seg.mk _ _ r s f t o : α → β) = f := rfl
id       └──────────────┘                      └─┘
src      └──────────────┘                              └─┘
typ      └──────────────┘                      └─┘
137  
138  @[simp] theorem coe_fn_to_order_embedding (f : r ≺i s) : (f.to_order_embedding : α → β) = f := rfl
id                                                   └┘      └─────────────────┘             └─┘
src                                                   └┘        └─────────────────┘                └─┘
typ                                                  └┘      └─────────────────┘             └─┘
doc    └──┘
139  
140  theorem coe_coe_fn (f : r ≺i s) : ((f : r ≼o s) : α → β) = f := rfl
id                            └┘           └┘               └─┘
src                            └┘              └┘                   └─┘
typ                           └┘           └┘               └─┘
doc                                            └┘
141  
142  theorem down' (f : r ≺i s) {b : β} : s b f.top ↔ ∃ a, f a = b :=
id                       └┘              └──┘       
src                       └┘                   └──┘         
typ                      └┘              └──┘       
143  f.down _
id   └───┘
src   └───┘
typ  └───┘
144  
145  theorem lt_top (f : r ≺i s) (a : α) : s (f a) f.top :=
id                        └┘                 └──┘
src                        └┘                       └──┘
typ                       └┘                 └──┘
146  f.down'.2 ⟨_, rfl⟩
id   └────┘      └─┘
src   └────┘      └─┘
typ  └────┘      └─┘
147  
148  theorem init [is_trans β s] (f : r ≺i s) {a : α} {b : β} (h : s b (f a)) : ∃ a', f a' = b :=
id                 └──────┘          └┘                                └┘  └┘  
src                └──────┘             └┘                                               
typ                └──────┘          └┘                                └┘  └┘  
149  f.down'.1 $ trans h $ f.lt_top _
id   └────┘    └───┘    └─────┘
src   └────┘    └───┘      └─────┘
typ  └────┘    └───┘    └─────┘
150  
151  instance has_coe_initial_seg [is_trans β s] : has_coe (r ≺i s) (r ≼i s) :=
id                                 └──────┘      └─────┘   └┘     └┘ 
src                                └──────┘        └─────┘    └┘       └┘
typ                                └──────┘      └─────┘   └┘     └┘ 
doc                                                                    └┘
152  ⟨λ f, ⟨f.to_order_embedding, λ a b, f.init⟩⟩
id         └─────────────────┘       └───┘
src          └─────────────────┘          └───┘
typ        └─────────────────┘       └───┘
153  
154  theorem coe_coe_fn' [is_trans β s] (f : r ≺i s) : ((f : r ≼i s) : α → β) = f := rfl
id                        └──────┘          └┘           └┘               └─┘
src                       └──────┘             └┘              └┘                   └─┘
typ                       └──────┘          └┘           └┘               └─┘
doc                                                            └┘
155  
156  theorem init_iff [is_trans β s] (f : r ≺i s) {a : α} {b : β} : s b (f a) ↔ ∃ a', f a' = b ∧ r a' a :=
id                     └──────┘          └┘                           └┘  └┘     └┘ 
src                    └──────┘             └┘                                             
typ                    └──────┘          └┘                           └┘  └┘     └┘ 
157  initial_seg.init_iff f
id   └──────────────────┘ 
src  └──────────────────┘
typ  └──────────────────┘ 
158  
159  theorem irrefl (r : α → α → Prop) [is_well_order α r] (f : r ≺i r) : false :=
id                                    └───────────┘          └┘     └───┘
src                                     └───────────┘             └┘      └───┘
typ                                   └───────────┘          └┘     └───┘
doc                                     └───────────┘
160  begin
st   └─────
161    have := f.lt_top f.top,
id             └──────┘ └───┘
src    └──────┘└──────┘└───┘
typ    └──────┘└──────┘└───┘
doc    └──────┘        
txt    └──────┘        
par    └──────┘        
pid    └───┘└─┘        
st   ───────────────────────┘└─
162    rw [show f f.top = f.top, from
id                      
src    └──┘               └──────
typ    └──┘               └──────
doc    └──┘                └──────
txt    └──┘                └──────
par    └──┘                └──────
pid      └┘                └──────
st   ─────────────────────────────────
163        initial_seg.eq ↑f (initial_seg.refl r) f.top] at this,
id         └────────────┘    └──────────────┘   └───┘
src  ─────┘└────────────┘  └──────────────┘ └┘└───┘└───────┘
typ  ─────┘└────────────┘  └──────────────┘└┘└───┘└───────┘
doc  ─────┘                 └──────────────┘ └┘     └───────┘
txt  ─────┘                                  └┘     └───────┘
par  ─────┘                                  └┘     └───────┘
pid  ─────┘                                  └┘     └──────┘
st   ─────────────────────────────────────────────────┘└──────┘└─
164    exact irrefl _ this
id           └────┘   └──┘
src    └────┘└────┘└─┘    
typ    └────┘└────┘└─┘└──┘
doc    └────┘      └─┘    
txt    └────┘      └─┘    
par    └────┘      └─┘    
pid               └─┘    
st   ─────────────────────┘
165  end
st   └─┘
166  
167  def lt_le (f : r ≺i s) (g : s ≼i t) : r ≺i t :=
id                   └┘         └┘      └┘ 
src                   └┘           └┘        └┘
typ                  └┘         └┘      └┘ 
doc                                └┘
168  ⟨@order_embedding.trans _ _ _ r s t f g, g f.top, λ a,
id     └───────────────────┘              └──┘    
src    └───────────────────┘                     └──┘
typ    └───────────────────┘              └──┘    
169   by simp only [g.init_iff, f.down', exists_and_distrib_left.symm,
src      └─────────┘          └┘       └┘                            └─
typ      └─────────┘└────────┘└┘└─────┘└┘└──────────────────────────┘└─
doc      └─────────┘          └┘       └┘                            └─
txt      └─────────┘          └┘       └┘                            └─
par      └─────────┘          └┘       └┘                            └─
pid          └──┘└┘          └┘       └┘                            └─
st      └──────────────────────────────────────────────────────────────
170     exists_swap, order_embedding.trans_apply, exists_eq_right']; refl⟩
id      └─────────┘  └─────────────────────────┘  └──────────────┘
src  ──┘└─────────┘└┘└─────────────────────────┘└┘└──────────────┘  └──┘
typ  ──┘└─────────┘└┘└─────────────────────────┘└┘└──────────────┘  └──┘
doc  ──┘           └┘                           └┘                  └──┘
txt  ──┘           └┘                           └┘                  └──┘
par  ──┘           └┘                           └┘                  └──┘
pid  ──┘           └┘                           └┘                
st   ───────────────────────────────────────────────────────────────────┘
171  
172  @[simp] theorem lt_le_apply [is_trans β s] [is_trans γ t] (f : r ≺i s) (g : s ≼i t) (a : α) : (f.lt_le g) a = g (f a) :=
id                                └──────┘     └──────┘          └┘         └┘             └────┘        
src                               └──────┘       └──────┘             └┘           └┘                └────┘      
typ                               └──────┘     └──────┘          └┘         └┘             └────┘        
doc    └──┘                                                                        └┘
173  order_embedding.trans_apply _ _ _
id   └─────────────────────────┘
src  └─────────────────────────┘
typ  └─────────────────────────┘
174  
175  @[simp] theorem lt_le_top (f : r ≺i s) (g : s ≼i t) : (f.lt_le g).top = g f.top := rfl
id                                   └┘         └┘      └────┘  └─┘    └──┘    └─┘
src                                   └┘           └┘        └────┘   └─┘      └──┘    └─┘
typ                                  └┘         └┘      └────┘  └─┘    └──┘    └─┘
doc    └──┘                                        └┘
176  
177  @[trans] protected def trans [is_trans γ t] (f : r ≺i s) (g : s ≺i t) : r ≺i t :=
id                                 └──────┘          └┘         └┘      └┘ 
src    └───┘                       └──────┘             └┘           └┘        └┘
typ                                └──────┘          └┘         └┘      └┘ 
doc    └───┘
178  lt_le f g
id   └───┘  
src  └───┘
typ  └───┘  
179  
180  @[simp] theorem trans_apply [is_trans β s] [is_trans γ t] (f : r ≺i s) (g : s ≺i t) (a : α) : (f.trans g) a = g (f a) :=
id                                └──────┘     └──────┘          └┘         └┘             └────┘        
src                               └──────┘       └──────┘             └┘           └┘                └────┘      
typ                               └──────┘     └──────┘          └┘         └┘             └────┘        
doc    └──┘
181  lt_le_apply _ _ _
id   └─────────┘
src  └─────────┘
typ  └─────────┘
182  
183  @[simp] theorem trans_top [is_trans β s] [is_trans γ t] (f : r ≺i s) (g : s ≺i t) : (f.trans g).top = g f.top := rfl
id                              └──────┘     └──────┘          └┘         └┘      └────┘  └─┘    └──┘    └─┘
src                             └──────┘       └──────┘             └┘           └┘        └────┘   └─┘      └──┘    └─┘
typ                             └──────┘     └──────┘          └┘         └┘      └────┘  └─┘    └──┘    └─┘
doc    └──┘
184  
185  def equiv_lt (f : r ≃o s) (g : s ≺i t) : r ≺i t :=
id                      └┘         └┘      └┘ 
src                      └┘           └┘        └┘
typ                     └┘         └┘      └┘ 
doc                      └┘
186  ⟨@order_embedding.trans _ _ _ r s t f g, g.top, λ c,
id     └───────────────────┘             └──┘    
src    └───────────────────┘                   └──┘
typ    └───────────────────┘             └──┘    
187   by simp only [g.down', coe_fn_coe_base, order_embedding.trans_apply]; exact
id                           └─────────────┘  └─────────────────────────┘
src      └─────────┘       └┘└─────────────┘└┘└─────────────────────────┘  └─────
typ      └─────────┘└─────┘└┘└─────────────┘└┘└─────────────────────────┘  └─────
doc      └─────────┘       └┘               └┘                             └─────
txt      └─────────┘       └┘               └┘                             └─────
par      └─────────┘       └┘               └┘                             └─────
pid          └──┘└┘       └┘               └┘                                  
st      └─────────────────────────────────────────────────────────────────────────
188   ⟨λ ⟨b, h⟩, ⟨f.symm b, by simp only [h, order_iso.apply_symm_apply, order_iso.coe_coe_fn]⟩, λ ⟨a, h⟩, ⟨f a, h⟩⟩⟩
id               └────┘                    └────────────────────────┘  └──────────────────┘             
src    └┘ └┘ └─┘ └────┘ └┘  └─────────┘ └┘└────────────────────────┘└┘└──────────────────┘└─┘ └┘ └┘ └─┘   └┘ └┘
typ    └┘└┘ └─┘ └────┘ └┘  └─────────┘└┘└────────────────────────┘└┘└──────────────────┘└─┘ └┘└┘└─┘  └┘ └┘
doc    └┘ └┘ └─┘        └┘  └─────────┘ └┘                          └┘                    └─┘ └┘ └┘ └─┘   └┘ └┘
txt    └┘ └┘ └─┘        └┘  └─────────┘ └┘                          └┘                    └─┘ └┘ └┘ └─┘   └┘ └┘
par    └┘ └┘ └─┘        └┘  └─────────┘ └┘                          └┘                    └─┘ └┘ └┘ └─┘   └┘ └┘
pid    └┘ └┘ └─┘        └┘  └──────────┘ └┘                          └┘                    └──┘ └┘ └┘ └─┘   └┘ └┘
st   ────────────────────────┘└──────────────────────────────────────────────────────────────┘└────────────────────┘
189  
190  def lt_equiv {r : α → α → Prop} {s : β → β → Prop} {t : γ → γ → Prop}
id                                                          
typ                                                         
191    (f : principal_seg r s) (g : s ≃o t) : principal_seg r t :=
id          └───────────┘          └┘     └───────────┘  
src         └───────────┘             └┘      └───────────┘
typ         └───────────┘          └┘     └───────────┘  
doc                                   └┘
192  ⟨@order_embedding.trans _ _ _ r s t f g, g f.top,
id     └───────────────────┘              └──┘
src    └───────────────────┘                     └──┘
typ    └───────────────────┘              └──┘
193    begin
st     └─────
194      intro x,
src      └─────┘
typ      └─────┘
doc      └─────┘
txt      └─────┘
par      └─────┘
pid           └┘
st   ──────────┘└─
195      rw [←g.right_inv x],
id            └─────────┘ 
src      └───┘└─────────┘ 
typ      └───┘└─────────┘
doc      └───┘            
txt      └───┘            
par      └───┘            
pid        └─┘            
st   ─────────────────────┘└──
196      simp only [order_iso.to_equiv_to_fun, coe_fn_coe_base, order_embedding.trans_apply],
id                  └───────────────────────┘  └─────────────┘  └─────────────────────────┘
src      └─────────┘└───────────────────────┘└┘└─────────────┘└┘└─────────────────────────┘
typ      └─────────┘└───────────────────────┘└┘└─────────────┘└┘└─────────────────────────┘
doc      └─────────┘                         └┘               └┘                           
txt      └─────────┘                         └┘               └┘                           
par      └─────────┘                         └┘               └┘                           
pid          └──┘└┘                         └┘               └┘                           
st   ──────────────────────────────────────────────────────────────────────────────────────┘└─
197      rw [←order_iso.ord'' g, f.down', exists_congr],
id            └─────────────┘            └──────────┘
src      └───┘└─────────────┘ └┘       └┘└──────────┘
typ      └───┘└─────────────┘└┘└─────┘└┘└──────────┘
doc      └───┘                └┘       └┘            
txt      └───┘                └┘       └┘            
par      └───┘                └┘       └┘            
pid        └─┘                └┘       └┘            
st   ─────────────────────────┘└───────┘└────────────┘└─
198      intro y, exact ⟨congr_arg g, λ h, g.to_equiv.bijective.1 h⟩
id                       └───────┘         └──────────────────┘
src      └─────┘  └────┘ └───────┘ └┘ └──┘└──────────────────┘└─┘ └─
typ      └─────┘  └────┘ └───────┘ └┘ └──┘└──────────────────┘└─┘ └─
doc      └─────┘  └────┘           └┘ └──┘                    └─┘ └─
txt      └─────┘  └────┘           └┘ └──┘                    └─┘ └─
par      └─────┘  └────┘           └┘ └──┘                    └─┘ └─
pid           └┘                  └┘ └──┘                    └─┘ 
st   ──────────┘└────────────────────────────────────────────────────
199    end⟩
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
200  
201  @[simp] theorem equiv_lt_apply [is_trans γ t] (f : r ≃o s) (g : s ≺i t) (a : α) : (equiv_lt f g) a = g (f a) :=
id                                   └──────┘          └┘         └┘             └──────┘         
src                                  └──────┘             └┘           └┘               └──────┘        
typ                                  └──────┘          └┘         └┘             └──────┘         
doc    └──┘                                               └┘
202  order_embedding.trans_apply _ _ _
id   └─────────────────────────┘
src  └─────────────────────────┘
typ  └─────────────────────────┘
203  
204  @[simp] theorem equiv_lt_top (f : r ≃o s) (g : s ≺i t) : (equiv_lt f g).top = g.top := rfl
id                                      └┘         └┘      └──────┘   └─┘   └──┘    └─┘
src                                      └┘           └┘       └──────┘     └─┘    └──┘    └─┘
typ                                     └┘         └┘      └──────┘   └─┘   └──┘    └─┘
doc    └──┘                              └┘
205  
206  instance [is_well_order β s] : subsingleton (r ≺i s) :=
id             └───────────┘      └──────────┘   └┘ 
src            └───────────┘        └──────────┘    └┘
typ            └───────────┘      └──────────┘   └┘ 
doc            └───────────┘
207  ⟨λ f g, begin
id       
typ      
st           └─────
208    have ef : (f : α → β) = g,
id                         
src    └────────┘  └─┘   └┘
typ    └────────┘ └─┘ └┘
doc    └────────┘  └─┘   └┘ 
txt    └────────┘  └─┘   └┘ 
par    └────────┘  └─┘   └┘ 
pid    └─────┘└─┘  └─┘   └┘ 
st   ──────────────────────────┘└─
209    { show ((f : r ≼i s) : α → β) = g,
id                  └┘            
src      └───┘   └─┘ └┘ └──┘   └┘ 
typ      └───┘  └─┘└┘└──┘ └┘ 
doc      └───┘   └─┘ └┘ └──┘   └┘ 
txt      └───┘   └─┘    └──┘   └┘ 
par      └───┘   └─┘    └──┘   └┘ 
pid      └───┘   └─┘    └──┘   └┘ 
st   ───┘└─────────────────────────────┘└─
210      rw @subsingleton.elim _ _ (f : r ≼i s) g, refl },
id           └───────────────┘               
src      └─┘ └───────────────┘└───┘  └─┘    └┘   └───┘
typ      └─┘ └───────────────┘└───┘ └─┘  └┘  └───┘
doc      └─┘                  └───┘  └─┘    └┘   └───┘
txt      └─┘                  └───┘  └─┘    └┘   └───┘
par      └─┘                  └───┘  └─┘    └┘   └───┘
pid                          └───┘  └─┘    └┘       
st   ───────────────────────────────────────────┘└─────┘└┘
211    have et : f.top = g.top,
id               └───┘   └───┘
src    └────────┘└───┘ └───┘
typ    └────────┘└───┘ └───┘
doc    └────────┘      
txt    └────────┘      
par    └────────┘      
pid    └─────┘└─┘      
st   ────────────────────────┘└─
212    { refine @is_extensional.ext _ s _ _ _ (λ x, _),
id               └────────────────┘   
src      └─────┘ └────────────────┘└─┘ └─────┘  └────┘
typ      └─────┘ └────────────────┘└─┘└─────┘  └────┘
doc      └─────┘                   └─┘ └─────┘  └────┘
txt      └─────┘                   └─┘ └─────┘  └────┘
par      └─────┘                   └─┘ └─────┘  └────┘
pid                               └─┘ └─────┘  └────┘
st   ───┘└───────────────────────────────────────────┘└─
213      simp only [f.down, g.down, ef, coe_fn_to_order_embedding] },
id                                  └┘  └───────────────────────┘
src      └─────────┘      └┘      └┘  └┘└───────────────────────┘└┘
typ      └─────────┘└────┘└┘└────┘└┘└┘└┘└───────────────────────┘└┘
doc      └─────────┘      └┘      └┘  └┘                         └┘
txt      └─────────┘      └┘      └┘  └┘                         └┘
par      └─────────┘      └┘      └┘  └┘                         └┘
pid          └──┘└┘      └┘      └┘  └┘                         
st   ─────────────────────────────────────────────────────────────┘└┘
214    cases f, cases g,
id                   
src    └────┘   └────┘
typ    └────┘  └────┘
doc    └────┘   └────┘
txt    └────┘   └────┘
par    └────┘   └────┘
pid                 
st   ────────┘└───────┘└─
215    have := order_embedding.eq_of_to_fun_eq ef; congr'
id             └─────────────────────────────┘ └┘
src    └──────┘└─────────────────────────────┘    └─────┘
typ    └──────┘└─────────────────────────────┘└┘  └─────┘
doc    └──────┘                                   └─────┘
txt    └──────┘                                   └─────┘
par    └──────┘                                   └─────┘
pid    └───┘└─┘                                         
st   ────────────────────────────────────────────────────┘
216  end⟩
st   └─┘
217  
218  theorem top_eq [is_well_order γ t]
id                   └───────────┘  
src                  └───────────┘
typ                  └───────────┘  
doc                  └───────────┘
219    (e : r ≃o s) (f : r ≺i t) (g : s ≺i t) : f.top = g.top :=
id           └┘         └┘         └┘     └──┘  └──┘
src           └┘           └┘           └┘       └──┘   └──┘
typ          └┘         └┘         └┘     └──┘  └──┘
doc           └┘
220  by rw subsingleton.elim f (principal_seg.equiv_lt e g); refl
id         └───────────────┘   └────────────────────┘  
src     └─┘└───────────────┘  └────────────────────┘    └────
typ     └─┘└───────────────┘ └────────────────────┘  └────
doc     └─┘                                             └────
txt     └─┘                                             └────
par     └─┘                                             └────
pid                                                        
st     └──────────────────────────────────────────────────────────
221  
src  
typ  
doc  
txt  
par  
pid  
st   
222  lemma top_lt_top {r : α → α → Prop} {s : β → β → Prop} {t : γ → γ → Prop}
id                                                              
typ                                                             
223    [is_trans β s] [is_well_order γ t]
id      └──────┘     └───────────┘  
src     └──────┘       └───────────┘
typ     └──────┘     └───────────┘  
doc                    └───────────┘
224    (f : principal_seg r s) (g : principal_seg s t) (h : principal_seg r t) : t h.top g.top :=
id          └───────────┘         └───────────┘         └───────────┘       └──┘ └──┘
src         └───────────┘           └───────────┘           └───────────┘           └──┘  └──┘
typ         └───────────┘         └───────────┘         └───────────┘       └──┘ └──┘
225  by { rw [subsingleton.elim h (f.trans g)], apply principal_seg.lt_top }
id            └───────────────┘   └─────┘           └──────────────────┘
src       └──┘└───────────────┘  └─────┘ └┘  └────┘└──────────────────┘
typ       └──┘└───────────────┘ └─────┘└┘  └────┘└──────────────────┘
doc       └──┘                           └┘  └────┘                    
txt       └──┘                           └┘  └────┘                    
par       └──┘                           └┘  └────┘                    
pid         └┘                           └┘                           
st     └────────────────────────────────────┘└────────────────────────────┘└┘
226  
227  /-- Any element of a well order yields a principal segment -/
228  def of_element {α : Type*} (r : α → α → Prop) (a : α) : subrel r {b | r b a} ≺i r :=
id                                                        └────┘         └┘ 
src                                                          └────┘              └┘
typ                                                       └────┘         └┘ 
doc                                                          └────┘
229  ⟨subrel.order_embedding _ _, a, λ b,
id    └────────────────────┘          
src   └────────────────────┘
typ   └────────────────────┘          
230    ⟨λ h, ⟨⟨_, h⟩, rfl⟩, λ ⟨⟨_, h⟩, rfl⟩, h⟩⟩
id                  └─┘            └─┘
src                   └─┘              └─┘
typ                 └─┘            └─┘
231  
232  @[simp] theorem of_element_apply {α : Type*} (r : α → α → Prop) [is_well_order α r] (a : α) (b) :
id                                                                  └───────────┘         
src                                                                   └───────────┘
typ                                                                 └───────────┘         
doc    └──┘                                                           └───────────┘
233    of_element r a b = b.1 := rfl
id     └────────┘          └─┘
src    └────────┘              └─┘
typ    └────────┘          └─┘
doc    └────────┘
234  
235  @[simp] theorem of_element_top {α : Type*} (r : α → α → Prop) (a : α) :
id                                                                    
typ                                                                   
doc    └──┘
236    (of_element r a).top = a := rfl
id      └────────┘   └─┘       └─┘
src     └────────┘     └─┘        └─┘
typ     └────────┘   └─┘       └─┘
doc     └────────┘
237  
238  /-- Restrict the codomain of a principal segment -/
239  def cod_restrict (p : set β) (f : r ≺i s)
id                         └─┘         └┘ 
src                        └─┘           └┘
typ                        └─┘         └┘ 
240    (H : ∀ a, f a ∈ p) (H₂ : f.top ∈ p) : r ≺i subrel s p :=
id                         └──┘       └┘ └────┘  
src                             └──┘         └┘ └────┘
typ                        └──┘       └┘ └────┘  
doc                                               └────┘
241  ⟨order_embedding.cod_restrict p f H, ⟨f.top, H₂⟩, λ ⟨b, h⟩,
id    └──────────────────────────┘      └──┘  └┘     
src   └──────────────────────────┘          └──┘
typ   └──────────────────────────┘      └──┘  └┘     
doc   └──────────────────────────┘
242    f.down'.trans $ exists_congr $ λ a,
id     └────┘└────┘   └──────────┘     
src     └────┘└────┘   └──────────┘
typ    └────┘└────┘   └──────────┘     
243    show (⟨f a, H a⟩ : p).1 = _ ↔ _, from ⟨subtype.eq, congr_arg _⟩⟩
id                                    └────────┘  └───────┘
src                                        └────────┘  └───────┘
typ                                   └────────┘  └───────┘
244  
245  @[simp] theorem cod_restrict_apply (p) (f : r ≺i s) (H H₂ a) : cod_restrict p f H H₂ a = ⟨f a, H a⟩ := rfl
id                                                └┘              └──────────┘    └┘             └─┘
src                                                └┘               └──────────┘                           └─┘
typ                                               └┘              └──────────┘    └┘             └─┘
doc    └──┘                                                         └──────────┘
246  
247  @[simp] theorem cod_restrict_top (p) (f : r ≺i s) (H H₂) : (cod_restrict p f H H₂).top = ⟨f.top, H₂⟩ := rfl
id                                              └┘             └──────────┘    └┘ └─┘    └──┘  └┘     └─┘
src                                              └┘              └──────────┘          └─┘     └──┘         └─┘
typ                                             └┘             └──────────┘    └┘ └─┘    └──┘  └┘     └─┘
doc    └──┘                                                      └──────────┘
248  
249  end principal_seg
250  
251  def initial_seg.lt_or_eq [is_well_order β s] (f : r ≼i s) :
id                             └───────────┘          └┘ 
src                            └───────────┘             └┘
typ                            └───────────┘          └┘ 
doc                            └───────────┘             └┘
252    (r ≺i s) ⊕ (r ≃o s) :=
id       └┘      └┘ 
src       └┘        └┘
typ      └┘      └┘ 
doc                  └┘
253  if h : surjective f then sum.inr (order_iso.of_surjective f h) else
id   └┘     └────────┘       └─────┘  └─────────────────────┘  
src  └┘     └────────┘        └─────┘  └─────────────────────┘
typ  └┘     └────────┘       └─────┘  └─────────────────────┘  
254  have h' : _, from (initial_seg.eq_or_principal f).resolve_left h,
id   └──┘               └─────────────────────────┘  └──────────┘  
src  └──┘               └─────────────────────────┘   └──────────┘
typ  └──┘               └─────────────────────────┘  └──────────┘  
255  sum.inl ⟨f, classical.some h', classical.some_spec h'⟩
id   └─────┘    └────────────┘ └┘  └─────────────────┘ └┘
src  └─────┘     └────────────┘     └─────────────────┘
typ  └─────┘    └────────────┘ └┘  └─────────────────┘ └┘
256  
257  @[simp] theorem initial_seg.lt_or_eq_apply_left [is_well_order β s]
id                                                    └───────────┘  
src                                                   └───────────┘
typ                                                   └───────────┘  
doc    └──┘                                           └───────────┘
258    (f : r ≼i s) {g} (h : f.lt_or_eq = sum.inl g) (a : α) : g a = f a :=
id           └┘            └───────┘  └─────┘                
src           └┘              └───────┘  └─────┘                  
typ          └┘            └───────┘  └─────┘                
doc           └┘
259  begin
st   └─────
260    unfold initial_seg.lt_or_eq at h,
src    └──────────────────────────────┘
typ    └──────────────────────────────┘
doc    └──────────────────────────────┘
txt    └──────────────────────────────┘
par    └──────────────────────────────┘
pid          └───────────────────┘└───┘
st   ─────────────────────────────────┘└─
261    by_cases sj : surjective f,
id                   └────────┘ 
src    └───────┘  └─┘└────────┘
typ    └───────┘  └─┘└────────┘
doc    └───────┘  └─┘          
txt    └───────┘  └─┘          
par    └───────┘  └─┘          
pid              └─┘          
st   ───────────────────────────┘└─
262    { rw dif_pos sj at h, cases h },
id          └─────┘ └┘             
src      └─┘└─────┘  └───┘  └────┘ 
typ      └─┘└─────┘└┘└───┘  └────┘
doc      └─┘         └───┘  └────┘ 
txt      └─┘         └───┘  └────┘ 
par      └─┘         └───┘  └────┘ 
pid                 └───┘        
st   ───┘└────────────────┘└────────┘└┘
263    { rw dif_neg sj at h, cases h, refl }
id          └─────┘ └┘             
src      └─┘└─────┘  └───┘  └────┘   └───┘
typ      └─┘└─────┘└┘└───┘  └────┘  └───┘
doc      └─┘         └───┘  └────┘   └───┘
txt      └─┘         └───┘  └────┘   └───┘
par      └─┘         └───┘  └────┘   └───┘
pid                 └───┘              
st   ─────────────────────┘└───────┘└─────┘└─
264  end
st   ──┘
265  
266  @[simp] theorem initial_seg.lt_or_eq_apply_right [is_well_order β s]
id                                                     └───────────┘  
src                                                    └───────────┘
typ                                                    └───────────┘  
doc    └──┘                                            └───────────┘
267    (f : r ≼i s) {g} (h : f.lt_or_eq = sum.inr g) (a : α) : g a = f a :=
id           └┘            └───────┘  └─────┘                
src           └┘              └───────┘  └─────┘                  
typ          └┘            └───────┘  └─────┘                
doc           └┘
268  begin
st   └─────
269    unfold initial_seg.lt_or_eq at h,
src    └──────────────────────────────┘
typ    └──────────────────────────────┘
doc    └──────────────────────────────┘
txt    └──────────────────────────────┘
par    └──────────────────────────────┘
pid          └───────────────────┘└───┘
st   ─────────────────────────────────┘└─
270    by_cases sj : surjective f,
id                   └────────┘ 
src    └───────┘  └─┘└────────┘
typ    └───────┘  └─┘└────────┘
doc    └───────┘  └─┘          
txt    └───────┘  └─┘          
par    └───────┘  └─┘          
pid              └─┘          
st   ───────────────────────────┘└─
271    {rw dif_pos sj at h, cases h, refl},
id         └─────┘ └┘             
src     └─┘└─────┘  └───┘  └────┘   └──┘
typ     └─┘└─────┘└┘└───┘  └────┘  └──┘
doc     └─┘         └───┘  └────┘   └──┘
txt     └─┘         └───┘  └────┘   └──┘
par     └─┘         └───┘  └────┘   └──┘
pid                └───┘       
st   ─────┘└─────┘└──────┘└───────┘└────┘└┘
272    {rw dif_neg sj at h, cases h}
id         └─────┘ └┘             
src     └─┘└─────┘  └───┘  └────┘
typ     └─┘└─────┘└┘└───┘  └────┘
doc     └─┘         └───┘  └────┘
txt     └─┘         └───┘  └────┘
par     └─┘         └───┘  └────┘
pid                └───┘       
st   ────────────────────┘└───────┘└─
273  end
st   ──┘
274  
275  def initial_seg.le_lt [is_well_order β s] [is_trans γ t] (f : r ≼i s) (g : s ≺i t) : r ≺i t :=
id                          └───────────┘     └──────┘          └┘         └┘      └┘ 
src                         └───────────┘       └──────┘             └┘           └┘        └┘
typ                         └───────────┘     └──────┘          └┘         └┘      └┘ 
doc                         └───────────┘                            └┘
276  match f.lt_or_eq with
id         └───────┘
src         └───────┘
typ        └───────┘
277  | sum.inl f' := f'.trans g
id     └─────┘ └┘      └────┘ 
src    └─────┘         └────┘
typ    └─────┘ └┘      └────┘ 
278  | sum.inr f' := principal_seg.equiv_lt f' g
id     └─────┘ └┘    └────────────────────┘    
src    └─────┘       └────────────────────┘
typ    └─────┘ └┘    └────────────────────┘    
279  end
280  
281  @[simp] theorem initial_seg.le_lt_apply [is_well_order β s] [is_trans γ t]
id                                            └───────────┘     └──────┘  
src                                           └───────────┘       └──────┘
typ                                           └───────────┘     └──────┘  
doc    └──┘                                   └───────────┘
282    (f : r ≼i s) (g : s ≺i t) (a : α) : (f.le_lt g) a = g (f a) :=
id           └┘         └┘             └────┘        
src           └┘           └┘                └────┘      
typ          └┘         └┘             └────┘        
doc           └┘
283  begin
st   └─────
284    delta initial_seg.le_lt, cases h : f.lt_or_eq with f' f',
id                                        └────────┘
src    └─────────────────────┘  └────┘ └─┘└────────┘└─────────┘
typ    └─────────────────────┘  └────┘ └─┘└────────┘└─────────┘
doc    └─────────────────────┘  └────┘ └─┘          └─────────┘
txt    └─────────────────────┘  └────┘ └─┘          └─────────┘
par    └─────────────────────┘  └────┘ └─┘          └─────────┘
pid         └────────────────┘        └─┘          └─────────┘
st   ────────────────────────┘└───────────────────────────────┘└─
285    { simp only [principal_seg.trans_apply, f.lt_or_eq_apply_left h] },
id                  └───────────────────────┘  └───────────────────┘ 
src      └─────────┘└───────────────────────┘└┘└───────────────────┘ └┘
typ      └─────────┘└───────────────────────┘└┘└───────────────────┘└┘
doc      └─────────┘                         └┘                      └┘
txt      └─────────┘                         └┘                      └┘
par      └─────────┘                         └┘                      └┘
pid          └──┘└┘                         └┘                      
st   ───┘└─────────────────────────────────────────────────────────────┘└┘
286    { simp only [principal_seg.equiv_lt_apply, f.lt_or_eq_apply_right h] }
id                  └──────────────────────────┘  └────────────────────┘ 
src      └─────────┘└──────────────────────────┘└┘└────────────────────┘ └┘
typ      └─────────┘└──────────────────────────┘└┘└────────────────────┘└┘
doc      └─────────┘                            └┘                       └┘
txt      └─────────┘                            └┘                       └┘
par      └─────────┘                            └┘                       └┘
pid          └──┘└┘                            └┘                       
st   ──────────────────────────────────────────────────────────────────────┘└─
287  end
st   ──┘
288  
289  namespace order_embedding
290  
291  def collapse_F [is_well_order β s] (f : r ≼o s) : Π a, {b // ¬ s (f a) b} :=
id                   └───────────┘          └┘                   
src                  └───────────┘             └┘                
typ                  └───────────┘          └┘                   
doc                  └───────────┘             └┘
292  (order_embedding.well_founded f $ is_well_order.wf s).fix $ λ a IH, begin
id    └──────────────────────────┘    └──────────────┘  └─┘       └┘
src   └──────────────────────────┘     └──────────────┘   └─┘
typ   └──────────────────────────┘    └──────────────┘  └─┘       └┘
st                                                                       └─────
293    let S := {b | ∀ a h, s (IH a h).1 b},
id                           └┘
src    └───────┘└──┘ └──┘       └──┘ 
typ    └───────┘└──┘ └──┘  └┘  └──┘ 
doc    └───────┘ └──┘ └──┘       └──┘ 
txt    └───────┘ └──┘ └──┘       └──┘ 
par    └───────┘ └──┘ └──┘       └──┘ 
pid    └───┘└─┘ └──┘ └──┘       └──┘ 
st   ─────────────────────────────────────┘└─
294    have : f a ∈ S, from λ a' h, ((trichotomous _ _)
id                                └──────────┘
src    └─────┘     └───┘ └─────┘  └──────────┘└─────
typ    └─────┘  └───┘ └─────┘  └──────────┘└─────
doc    └─────┘      └───┘ └─────┘              └─────
txt    └─────┘      └───┘ └─────┘              └─────
par    └─────┘      └───┘ └─────┘              └─────
pid    └───┘└┘      └───┘ └─────┘              └─────
st   ───────────────┘└──────────────────────────────────
295      .resolve_left $ λ h', (IH a' h).2 $ trans (f.ord'.1 h) h')
id                                           └───┘
src  ─────────────────┘  └───┘      └──┘ └───┘       └─┘ └┘  └─
typ  ─────────────────┘  └───┘      └──┘ └───┘       └─┘ └┘  └─
doc  ─────────────────┘  └───┘      └──┘             └─┘ └┘  └─
txt  ─────────────────┘  └───┘      └──┘             └─┘ └┘  └─
par  ─────────────────┘  └───┘      └──┘             └─┘ └┘  └─
pid  ─────────────────┘  └───┘      └──┘             └─┘ └┘  └─
st   ───────────────────────────────────────────────────────────────
296      .resolve_left $ λ h', (IH a' h).2 $ h' ▸ f.ord'.1 h,
id                              └┘               └────┘
src  ─────────────────┘  └───┘      └──┘   └────┘└─┘
typ  ─────────────────┘  └───┘ └┘   └──┘   └────┘└─┘
doc  ─────────────────┘  └───┘      └──┘          └─┘
txt  ─────────────────┘  └───┘      └──┘          └─┘
par  ─────────────────┘  └───┘      └──┘          └─┘
pid  ─────────────────┘  └───┘      └──┘          └─┘
st   ──────────────────────────────────────────────────────┘└─
297    exact ⟨(is_well_order.wf s).min S ⟨_, this⟩,
id                                     
src    └────┘                   └────┘  └─┘    └──
typ    └────┘                   └────┘ └─┘    └──
doc    └────┘                   └────┘  └─┘    └──
txt    └────┘                   └────┘  └─┘    └──
par    └────┘                   └────┘  └─┘    └──
pid                            └────┘  └─┘    └──
st   ───────────────────────────────────────────────
298     (is_well_order.wf s).not_lt_min _ _ this⟩
id       └──────────────┘                  └──┘
src  ──┘ └──────────────┘ └───────────────┘    └┘
typ  ──┘ └──────────────┘└───────────────┘└──┘└┘
doc  ──┘                  └───────────────┘    └┘
txt  ──┘                  └───────────────┘    └┘
par  ──┘                  └───────────────┘    └┘
pid  ──┘                  └───────────────┘    
st   ────────────────────────────────────────────┘
299  end
st   └─┘
300  
301  theorem collapse_F.lt [is_well_order β s] (f : r ≼o s) {a : α}
id                          └───────────┘          └┘        
src                         └───────────┘             └┘
typ                         └───────────┘          └┘        
doc                         └───────────┘             └┘
302     : ∀ {a'}, r a' a → s (collapse_F f a').1 (collapse_F f a).1 :=
id           └┘    └┘      └────────┘  └┘    └────────┘   
src                           └────────┘         └────────┘     
typ          └┘    └┘      └────────┘  └┘    └────────┘   
303  show (collapse_F f a).1 ∈ {b | ∀ a' (h : r a' a), s (collapse_F f a').1 b}, begin
id         └────────┘           └┘       └┘      └────────┘  └┘   
src        └────────┘                                  └────────┘      
typ        └────────┘           └┘       └┘      └────────┘  └┘   
st                                                                               └─────
304    unfold collapse_F, rw well_founded.fix_eq,
id                           └─────────────────┘
src    └───────────────┘  └─┘└─────────────────┘
typ    └───────────────┘  └─┘└─────────────────┘
doc    └───────────────┘  └─┘
txt    └───────────────┘  └─┘
par    └───────────────┘  └─┘
pid          └─────────┘    
st   ──────────────────┘└──────────────────────┘└─
305    apply well_founded.min_mem _ _
id           └──────────────────┘
src    └────┘└──────────────────┘└───┘
typ    └────┘└──────────────────┘└───┘
doc    └────┘                    └───┘
txt    └────┘                    └───┘
par    └────┘                    └───┘
pid                             └──┘
st   ────────────────────────────────┘
306  end
st   └─┘
307  
308  theorem collapse_F.not_lt [is_well_order β s] (f : r ≼o s) (a : α)
id                              └───────────┘          └┘        
src                             └───────────┘             └┘
typ                             └───────────┘          └┘        
doc                             └───────────┘             └┘
309     {b} (h : ∀ a' (h : r a' a), s (collapse_F f a').1 b) : ¬ s b (collapse_F f a).1 :=
id                 └┘       └┘      └────────┘  └┘           └────────┘   
src                                    └────────┘                   └────────┘     
typ                └┘       └┘      └────────┘  └┘           └────────┘   
310  begin
st   └─────
311    unfold collapse_F, rw well_founded.fix_eq,
id                           └─────────────────┘
src    └───────────────┘  └─┘└─────────────────┘
typ    └───────────────┘  └─┘└─────────────────┘
doc    └───────────────┘  └─┘
txt    └───────────────┘  └─┘
par    └───────────────┘  └─┘
pid          └─────────┘    
st   ──────────────────┘└──────────────────────┘└─
312    exact well_founded.not_lt_min _ _ _
id           └─────────────────────┘
src    └────┘└─────────────────────┘└──────
typ    └────┘└─────────────────────┘└──────
doc    └────┘                       └──────
txt    └────┘                       └──────
par    └────┘                       └──────
pid                                └──────
st   ──────────────────────────────────────
313      (show b ∈ {b | ∀ a' (h : r a' a), s (collapse_F f a').1 b}, from h)
id                                      └────────┘                 
src  ───┘      └──┘ └───────┘       └────────┘   └──┘ └──────┘ └┘
typ  ───┘     └──┘ └───────┘    └────────┘  └──┘ └──────┘└┘
doc  ───┘        └──┘ └───────┘                    └──┘ └──────┘ └┘
txt  ───┘        └──┘ └───────┘                    └──┘ └──────┘ └┘
par  ───┘        └──┘ └───────┘                    └──┘ └──────┘ └┘
pid  ───┘        └──┘ └───────┘                    └──┘ └──────┘ 
st   ───────────────────────────────────────────────────────────────────────┘
314  end
st   └─┘
315  
316  /-- Construct an initial segment from an order embedding. -/
317  def collapse [is_well_order β s] (f : r ≼o s) : r ≼i s :=
id                 └───────────┘          └┘      └┘ 
src                └───────────┘             └┘        └┘
typ                └───────────┘          └┘      └┘ 
doc                └───────────┘             └┘        └┘
318  by haveI := order_embedding.is_well_order f; exact
id               └───────────────────────────┘ 
src     └───────┘└───────────────────────────┘   └────┘
typ     └───────┘└───────────────────────────┘  └────┘
doc     └───────┘                                └────┘
txt     └───────┘                                └────┘
par     └───────┘                                └────┘
pid          └─┘                                     
st     └────────────────────────────────────────────────
319  ⟨order_embedding.of_monotone
id    └─────────────────────────┘
src   └─────────────────────────┘
typ   └─────────────────────────┘
doc   └─────────────────────────┘
txt                              
par                              
pid                              
st   ─────────────────────────────
320    (λ a, (collapse_F f a).1) (λ a b, collapse_F.lt f),
id            └────────┘                 └───────────┘ 
src  ─┘  └──┘ └────────┘  └───┘  └────┘└───────────┘ └─┘
typ  ─┘  └──┘ └────────┘  └───┘  └────┘└───────────┘└─┘
doc  ─┘  └──┘             └───┘  └────┘              └─┘
txt  ─┘  └──┘             └───┘  └────┘              └─┘
par  ─┘  └──┘             └───┘  └────┘              └─┘
pid  ─┘  └──┘             └───┘  └────┘              └─┘
st   ──────────────────────────────────────────────────────
321  λ a b, acc.rec_on ((is_well_order.wf s).apply b) (λ b H IH a h, begin
id          └────────┘   └──────────────┘ 
src   └────┘└────────┘  └──────────────┘ └──────┘ └┘  └───────────┘     
typ   └────┘└────────┘  └──────────────┘└──────┘ └┘  └───────────┘     
doc   └────┘                             └──────┘ └┘  └───────────┘     
txt   └────┘                             └──────┘ └┘  └───────────┘     
par   └────┘                             └──────┘ └┘  └───────────┘     
pid   └────┘                             └──────┘ └┘  └───────────┘     
st   ───────────────────────────────────────────────────────────────┘└─────
322    let S := {a | ¬ s (collapse_F f a).1 b},
id                      └────────┘       
src  ─┘└───────┘└──┘   └────────┘  └──┘ └─
typ  ─┘└───────┘└──┘  └────────┘ └──┘└─
doc  ─┘└───────┘ └──┘               └──┘ └─
txt  ─┘└───────┘ └──┘               └──┘ └─
par  ─┘└───────┘ └──┘               └──┘ └─
pid  ──────────┘ └──┘               └──┘ └──
st   ────────────────────────────────────────┘└─
323    have : S.nonempty := ⟨_, asymm h⟩,
id            └────────┘        └───┘ 
src  ─┘└─────┘└────────┘└──┘ └─┘└───┘ └─
typ  ─┘└─────┘└────────┘└──┘ └─┘└───┘└─
doc  ─┘└─────┘└────────┘└──┘ └─┘      └─
txt  ─┘└─────┘          └──┘ └─┘      └─
par  ─┘└─────┘          └──┘ └─┘      └─
pid  ────────┘          └──┘ └─┘      └──
st   ──────────────────────────────────┘└─
324    existsi (is_well_order.wf r).min S this,
id              └──────────────┘        └──┘
src  ─┘└──────┘ └──────────────┘ └────┘     └─
typ  ─┘└──────┘ └──────────────┘└────┘└──┘└─
doc  ─┘└──────┘                  └────┘     └─
txt  ─┘└──────┘                  └────┘     └─
par  ─┘└──────┘                  └────┘     └─
pid  ─────────┘                  └────┘     └─
st   ────────────────────────────────────────┘└─
325    refine ((@trichotomous _ s _ _ _).resolve_left _).resolve_right _,
id               └──────────┘   
src  ─┘└─────┘   └──────────┘└─┘ └─────────────────────────────────────┘└─
typ  ────────┘   └──────────┘└─┘└────────────────────────────────────────
doc  ─┘└─────┘               └─┘ └─────────────────────────────────────┘└─
txt  ─┘└─────┘               └─┘ └─────────────────────────────────────┘└─
par  ────────┘               └─┘ └────────────────────────────────────────
pid  ────────┘               └─┘ └────────────────────────────────────────
st   ──────────────────────────────────────────────────────────────────┘└─
326    { exact (is_well_order.wf r).min_mem S this },
id              └──────────────┘            └──┘
src  ─────────┘ └──────────────┘ └────────┘     └───
typ  ─────────┘ └──────────────┘└────────┘└──┘└───
doc  ─────────┘                  └────────┘     └───
txt  ─────────┘                  └────────┘     └───
par  ─────────┘                  └────────┘     └───
pid  ─────────┘                  └────────┘     └───
st   ──┘└─────────────────────────────────────────┘└─
327    { refine collapse_F.not_lt f _ (λ a' h', _),
id              └───────────────┘ 
src  ───┘└─────┘└───────────────┘ └─┘  └────────┘└─
typ  ──────────┘└───────────────┘└─┘  └───────────
doc  ───┘└─────┘                  └─┘  └────────┘└─
txt  ───┘└─────┘                  └─┘  └────────┘└─
par  ──────────┘                  └─┘  └───────────
pid  ──────────┘                  └─┘  └───────────
st   ────────────────────────────────────────────┘└─
328      by_contradiction hn,
src  ───┘└─────────────────┘└─
typ  ───┘└─────────────────┘└─
doc  ───┘└─────────────────┘└─
txt  ───┘└─────────────────┘└─
par  ───┘└─────────────────┘└─
pid  ─────────────────────────
st   ──────────────────────┘└─
329      exact (is_well_order.wf r).not_lt_min S this hn h' }
id              └──────────────┘               └──┘ └┘ └┘
src  ─────────┘ └──────────────┘ └───────────┘         └──
typ  ─────────┘ └──────────────┘└───────────┘└──┘└┘└┘└──
doc  ─────────┘                  └───────────┘         └──
txt  ─────────┘                  └───────────┘         └──
par  ─────────┘                  └───────────┘         └──
pid  ─────────┘                  └───────────┘         └──
st   ──────────────────────────────────────────────────────┘└─
330  end) a⟩
src  ────┘ └─
typ  ────┘ └─
doc  ────┘ └─
txt  ────┘ └─
par  ────┘ └─
pid  ────┘ 
st   ──┘└────
331  
src  
typ  
doc  
txt  
par  
pid  
st   
332  theorem collapse_apply [is_well_order β s] (f : r ≼o s)
id                           └───────────┘          └┘ 
src                          └───────────┘             └┘
typ                          └───────────┘          └┘ 
doc                          └───────────┘             └┘
333    (a) : collapse f a = (collapse_F f a).1 := rfl
id           └──────┘     └────────┘        └─┘
src          └──────┘       └────────┘          └─┘
typ          └──────┘     └────────┘        └─┘
doc          └──────┘
334  
335  end order_embedding
336  
337  section well_ordering_thm
338  parameter {σ : Type u}
339  open function
340  
341  theorem nonempty_embedding_to_cardinal : nonempty (σ ↪ cardinal.{u}) :=
id                                            └──────┘    └──────┘
src                                           └──────┘     └──────┘
typ                                           └──────┘    └──────┘
doc                                                         └──────┘
342  embedding.total.resolve_left $ λ ⟨⟨f, hf⟩⟩,
id   └─────────────┘└───────────┘        └┘
src  └─────────────┘└───────────┘
typ  └─────────────┘└───────────┘        └┘
343    let g : σ → cardinal.{u} := inv_fun f in
id               └──────┘        └─────┘
src                └──────┘        └─────┘
typ              └──────┘        └─────┘
doc                └──────┘        └─────┘
344    let ⟨x, (hx : g x = 2 ^ sum g)⟩ := inv_fun_surjective hf (2 ^ sum g) in
id     └─┘                 └─┘       └────────────────┘        └─┘ 
src                          └─┘        └────────────────┘        └─┘
typ    └─┘                 └─┘       └────────────────┘        └─┘ 
doc                            └─┘                                   └─┘
345    have g x ≤ sum g, from le_sum.{u u} g x,
id              └─┘        └────┘       
src              └─┘         └────┘
typ             └─┘        └────┘       
doc               └─┘
346    not_le_of_gt (by rw hx; exact cantor _) this
id     └──────────┘        └┘        └────┘    └──┘
src    └──────────┘     └─┘    └────┘└────┘└┘
typ    └──────────┘     └─┘└┘  └────┘└────┘└┘  └──┘
doc                     └─┘    └────┘      └┘
txt                     └─┘    └────┘      └┘
par                     └─┘    └────┘      └┘
pid                                      └┘
st                     └────────────────────┘
347  
348  /-- An embedding of any type to the set of cardinals. -/
349  def embedding_to_cardinal : σ ↪ cardinal.{u} := classical.choice nonempty_embedding_to_cardinal
id                                 └──────┘        └──────────────┘ └────────────────────────────┘
src                                 └──────┘        └──────────────┘ └────────────────────────────┘
typ                                └──────┘        └──────────────┘ └────────────────────────────┘
doc                                  └──────┘
350  
351  /-- The relation whose existence is given by the well-ordering theorem -/
352  def well_ordering_rel : σ → σ → Prop := embedding_to_cardinal ⁻¹'o (<)
id                                         └───────────────────┘ └──┘ 
src                                          └───────────────────┘ └──┘ 
typ                                        └───────────────────┘ └──┘ 
doc                                          └───────────────────┘ └──┘
353  
354  instance well_ordering_rel.is_well_order : is_well_order σ well_ordering_rel :=
id                                              └───────────┘  └───────────────┘
src                                             └───────────┘   └───────────────┘
typ                                             └───────────┘  └───────────────┘
doc                                             └───────────┘   └───────────────┘
355  (order_embedding.preimage _ _).is_well_order
id    └──────────────────────┘     └───────────┘
src   └──────────────────────┘     └───────────┘
typ   └──────────────────────┘     └───────────┘
doc   └──────────────────────┘
356  
357  end well_ordering_thm
358  
359  structure Well_order : Type (u+1) :=
360  (α : Type u)
id        └──┘
typ       └──┘
361  (r : α → α → Prop)
id          
typ         
362  (wo : is_well_order α r)
id         └───────────┘  
src        └───────────┘
typ        └───────────┘  
doc        └───────────┘
363  
364  attribute [instance] Well_order.wo
id                        └───────────┘
src                       └───────────┘
typ                       └───────────┘
365  
366  namespace Well_order
367  
368  instance : inhabited Well_order := ⟨⟨pempty, _, empty_relation.is_well_order⟩⟩
id              └───────┘ └────────┘      └────┘     └──────────────────────────┘
src             └───────┘ └────────┘      └────┘     └──────────────────────────┘
typ             └───────┘ └────────┘      └────┘     └──────────────────────────┘
doc                                       └────┘
369  
370  end Well_order
371  
372  instance ordinal.is_equivalent : setoid Well_order :=
id                                    └────┘ └────────┘
src                                   └────┘ └────────┘
typ                                   └────┘ └────────┘
373  { r     := λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, nonempty (r ≃o s),
id                                    └──────┘    └┘
src                                       └──────┘    └┘
typ                                   └──────┘    └┘
doc                                                   └┘
374    iseqv := ⟨λ⟨α, r, _⟩, ⟨order_iso.refl _⟩,
id                           └────────────┘
src                           └────────────┘
typ                          └────────────┘
375      λ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨e⟩, ⟨e.symm⟩,
id                               └───┘
src                                  └───┘
typ                              └───┘
376      λ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨e₁⟩ ⟨e₂⟩, ⟨e₁.trans e₂⟩⟩ }
id                                   └┘  └┘      └────┘
src                                                   └────┘
typ                                  └┘  └┘      └────┘
377  
378  /-- `ordinal.{u}` is the type of well orders in `Type u`,
379    quotient by order isomorphism. -/
380  def ordinal : Type (u + 1) := quotient ordinal.is_equivalent
id                                 └──────┘ └───────────────────┘
src                                └──────┘ └───────────────────┘
typ                                └──────┘ └───────────────────┘
381  
382  namespace ordinal
383  
384  /-- The order type of a well order is an ordinal. -/
385  def type (r : α → α → Prop) [wo : is_well_order α r] : ordinal :=
id                                   └───────────┘      └─────┘
src                                    └───────────┘        └─────┘
typ                                  └───────────┘      └─────┘
doc                                    └───────────┘        └─────┘
386  ⟦⟨α, r, wo⟩⟧
id        └┘ 
src            
typ       └┘ 
387  
388  /-- The order type of an element inside a well order. -/
389  def typein (r : α → α → Prop) [is_well_order α r] (a : α) : ordinal :=
id                                └───────────┘             └─────┘
src                                 └───────────┘                └─────┘
typ                               └───────────┘             └─────┘
doc                                 └───────────┘                └─────┘
390  type (subrel r {b | r b a})
id   └──┘  └────┘       
src  └──┘  └────┘   
typ  └──┘  └────┘       
doc  └──┘  └────┘
391  
392  theorem type_def (r : α → α → Prop) [wo : is_well_order α r] :
id                                           └───────────┘  
src                                            └───────────┘
typ                                          └───────────┘  
doc                                            └───────────┘
393    @eq ordinal ⟦⟨α, r, wo⟩⟧ (type r) := rfl
id      └┘ └─────┘      └┘   └──┘      └─┘
src     └┘ └─────┘             └──┘       └─┘
typ     └┘ └─────┘      └┘   └──┘      └─┘
doc        └─────┘               └──┘
394  
395  @[simp] theorem type_def' (r : α → α → Prop) [is_well_order α r] {wo} :
id                                               └───────────┘  
src                                                └───────────┘
typ                                              └───────────┘  
doc    └──┘                                        └───────────┘
396    @eq ordinal ⟦⟨α, r, wo⟩⟧ (type r) := rfl
id      └┘ └─────┘      └┘   └──┘      └─┘
src     └┘ └─────┘             └──┘       └─┘
typ     └┘ └─────┘      └┘   └──┘      └─┘
doc        └─────┘               └──┘
397  
398  theorem type_eq {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                  
typ                                                 
399    [is_well_order α r] [is_well_order β s] :
id      └───────────┘     └───────────┘  
src     └───────────┘       └───────────┘
typ     └───────────┘     └───────────┘  
doc     └───────────┘       └───────────┘
400    type r = type s ↔ nonempty (r ≃o s) := quotient.eq
id     └──┘   └──┘   └──────┘   └┘      └─────────┘
src    └──┘    └──┘    └──────┘    └┘       └─────────┘
typ    └──┘   └──┘   └──────┘   └┘      └─────────┘
doc    └──┘     └──┘                 └┘
401  
402  @[simp] lemma type_out (o : ordinal) : type o.out.r = o :=
id                               └─────┘    └──┘ └──┘└┘  
src                              └─────┘    └──┘  └──┘└┘ 
typ                              └─────┘    └──┘ └──┘└┘  
doc    └──┘                      └─────┘    └──┘  └──┘
403  by { refine eq.trans _ (by rw [←quotient.out_eq o]), cases quotient.out o, refl }
id               └──────┘            └─────────────┘           └──────────┘ 
src       └─────┘└──────┘└─┘   └───┘└─────────────┘   └────┘└──────────┘   └───┘
typ       └─────┘└──────┘└─┘   └───┘└─────────────┘  └────┘└──────────┘  └───┘
doc       └─────┘        └─┘   └───┘                  └────┘└──────────┘   └───┘
txt       └─────┘        └─┘   └───┘                  └────┘               └───┘
par       └─────┘        └─┘   └───┘                  └────┘               └───┘
pid                     └─┘   └────┘                └┘                          
st     └──────────────────────┘└─────────────────────┘└────────────────────┘└─────┘└┘
404  
405  @[elab_as_eliminator] theorem induction_on {C : ordinal → Prop}
id                                                   └─────┘
src                                                  └─────┘
typ                                                  └─────┘
doc    └────────────────┘                            └─────┘
406    (o : ordinal) (H : ∀ α r [is_well_order α r], C (type r)) : C o :=
id          └─────┘            └───────────┘       └──┘       
src         └─────┘              └───────────┘          └──┘
typ         └─────┘            └───────────┘       └──┘       
doc         └─────┘              └───────────┘          └──┘
407  quot.induction_on o $ λ ⟨α, r, wo⟩, @H α r wo
id   └───────────────┘          └┘    
src  └───────────────┘
typ  └───────────────┘          └┘    
408  
409  /-- Ordinal less-equal is defined such that
410    well orders `r` and `s` satisfy `type r ≤ type s` if there exists
411    a function embedding `r` as an initial segment of `s`. -/
412  protected def le (a b : ordinal) : Prop :=
id                           └─────┘
src                          └─────┘
typ                          └─────┘
doc                          └─────┘
413  quotient.lift_on₂ a b (λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, nonempty (r ≼i s)) $
id   └───────────────┘                          └──────┘    └┘
src  └───────────────┘                                └──────┘    └┘
typ  └───────────────┘                          └──────┘    └┘
doc                                                               └┘
414  λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
id                                                       
typ                                                      
415  propext ⟨
id   └─────┘
src  └─────┘
typ  └─────┘
416    λ ⟨h⟩, ⟨(initial_seg.of_iso f.symm).trans $
id            └────────────────┘  └───┘ └───┘
src             └────────────────┘  └───┘ └───┘
typ           └────────────────┘  └───┘ └───┘
doc             └────────────────┘        └───┘
417      h.trans (initial_seg.of_iso g)⟩,
id        └────┘  └────────────────┘
src       └────┘  └────────────────┘
typ       └────┘  └────────────────┘
doc       └────┘  └────────────────┘
418    λ ⟨h⟩, ⟨(initial_seg.of_iso f).trans $
id            └────────────────┘   └───┘
src             └────────────────┘   └───┘
typ           └────────────────┘   └───┘
doc             └────────────────┘   └───┘
419      h.trans (initial_seg.of_iso g.symm)⟩⟩
id        └────┘  └────────────────┘  └───┘
src       └────┘  └────────────────┘  └───┘
typ       └────┘  └────────────────┘  └───┘
doc       └────┘  └────────────────┘
420  
421  instance : has_le ordinal := ⟨ordinal.le⟩
id              └────┘ └─────┘     └────────┘
src             └────┘ └─────┘     └────────┘
typ             └────┘ └─────┘     └────────┘
doc                    └─────┘     └────────┘
422  
423  theorem type_le {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                  
typ                                                 
424    [is_well_order α r] [is_well_order β s] :
id      └───────────┘     └───────────┘  
src     └───────────┘       └───────────┘
typ     └───────────┘     └───────────┘  
doc     └───────────┘       └───────────┘
425    type r ≤ type s ↔ nonempty (r ≼i s) := iff.rfl
id     └──┘   └──┘   └──────┘   └┘      └─────┘
src    └──┘    └──┘    └──────┘    └┘       └─────┘
typ    └──┘   └──┘   └──────┘   └┘      └─────┘
doc    └──┘     └──┘                 └┘
426  
427  theorem type_le' {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                   
typ                                                  
428    [is_well_order α r] [is_well_order β s] : type r ≤ type s ↔ nonempty (r ≼o s) :=
id      └───────────┘     └───────────┘      └──┘   └──┘   └──────┘   └┘ 
src     └───────────┘       └───────────┘        └──┘    └──┘    └──────┘    └┘
typ     └───────────┘     └───────────┘      └──┘   └──┘   └──────┘   └┘ 
doc     └───────────┘       └───────────┘        └──┘     └──┘                 └┘
429  ⟨λ ⟨f⟩, ⟨f⟩, λ ⟨f⟩, ⟨f.collapse⟩⟩
id                     └───────┘
src                        └───────┘
typ                    └───────┘
doc                        └───────┘
430  
431  /-- Ordinal less-than is defined such that
432    well orders `r` and `s` satisfy `type r < type s` if there exists
433    a function embedding `r` as a principal segment of `s`. -/
434  def lt (a b : ordinal) : Prop :=
id                 └─────┘
src                └─────┘
typ                └─────┘
doc                └─────┘
435  quotient.lift_on₂ a b (λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, nonempty (r ≺i s)) $
id   └───────────────┘                          └──────┘    └┘
src  └───────────────┘                                └──────┘    └┘
typ  └───────────────┘                          └──────┘    └┘
436  λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
id                                                        
typ                                                       
437  by exactI propext ⟨
id             └─────┘
src     └─────┘└─────┘ 
typ     └─────┘└─────┘ 
doc     └─────┘        
txt     └─────┘        
par     └─────┘        
pid                   
st     └─────────────────
438    λ ⟨h⟩, ⟨principal_seg.equiv_lt f.symm $
id                                   └────┘
src  ─┘ └┘ └─┘                       └────┘ 
typ  ─┘ └┘└─┘                       └────┘ 
doc  ─┘ └┘ └─┘                              
txt  ─┘ └┘ └─┘                              
par  ─┘ └┘ └─┘                              
pid  ─┘ └┘ └─┘                              
st   ──────────────────────────────────────────
439      h.lt_le (initial_seg.of_iso g)⟩,
id        └────┘
src  ───┘ └────┘                    └───
typ  ───┘ └────┘                    └───
doc  ───┘                           └───
txt  ───┘                           └───
par  ───┘                           └───
pid  ───┘                           └───
st   ─────────────────────────────────────
440    λ ⟨h⟩, ⟨principal_seg.equiv_lt f $
id            └────────────────────┘ 
src  ─┘ └┘ └─┘ └────────────────────┘  
typ  ─┘ └┘└─┘ └────────────────────┘ 
doc  ─┘ └┘ └─┘                         
txt  ─┘ └┘ └─┘                         
par  ─┘ └┘ └─┘                         
pid  ─┘ └┘ └─┘                         
st   ─────────────────────────────────────
441      h.lt_le (initial_seg.of_iso g.symm)⟩⟩
id                └────────────────┘ └────┘
src  ───┘        └────────────────┘└────┘└───
typ  ───┘        └────────────────┘└────┘└───
doc  ───┘        └────────────────┘      └───
txt  ───┘                                └───
par  ───┘                                └───
pid  ───┘                                └─┘
st   ──────────────────────────────────────────
442  
src  
typ  
doc  
txt  
par  
pid  
st   
443  instance : has_lt ordinal := ⟨ordinal.lt⟩
id              └────┘ └─────┘     └────────┘
src             └────┘ └─────┘     └────────┘
typ             └────┘ └─────┘     └────────┘
doc                    └─────┘     └────────┘
444  
445  @[simp] theorem type_lt {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                          
typ                                                         
doc    └──┘
446    [is_well_order α r] [is_well_order β s] :
id      └───────────┘     └───────────┘  
src     └───────────┘       └───────────┘
typ     └───────────┘     └───────────┘  
doc     └───────────┘       └───────────┘
447    type r < type s ↔ nonempty (r ≺i s) := iff.rfl
id     └──┘   └──┘   └──────┘   └┘      └─────┘
src    └──┘    └──┘    └──────┘    └┘       └─────┘
typ    └──┘   └──┘   └──────┘   └┘      └─────┘
doc    └──┘     └──┘
448  
449  instance : partial_order ordinal :=
id              └───────────┘ └─────┘
src             └───────────┘ └─────┘
typ             └───────────┘ └─────┘
doc                           └─────┘
450  { le := (≤),
id           
src          
typ          
451    lt := (<),
id           
src          
typ          
452    le_refl := quot.ind $ by exact λ ⟨α, r, wo⟩, ⟨initial_seg.refl _⟩,
id                └──────┘                           └──────────────┘
src                             └────┘ └┘ └┘ └┘  └─┘ └──────────────┘└─┘
typ               └──────┘      └────┘ └┘ └┘ └┘  └─┘ └──────────────┘└─┘
doc                             └────┘ └┘ └┘ └┘  └─┘ └──────────────┘└─┘
txt                             └────┘ └┘ └┘ └┘  └─┘                 └─┘
par                             └────┘ └┘ └┘ └┘  └─┘                 └─┘
pid                                   └┘ └┘ └┘  └─┘                 └─┘
st                             └───────────────────────────────────────┘
453    le_trans := λ a b c, quotient.induction_on₃ a b c $
id                       └────────────────────┘   
src                         └────────────────────┘
typ                      └────────────────────┘   
454      λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨f⟩ ⟨g⟩, ⟨f.trans g⟩,
id                                           └────┘
src                                                 └────┘
typ                                          └────┘
doc                                                 └────┘
455    lt_iff_le_not_le := λ a b, quotient.induction_on₂ a b $
id                              └────────────────────┘  
src                               └────────────────────┘
typ                             └────────────────────┘  
456      λ ⟨α, r, _⟩ ⟨β, s, _⟩, by exactI
id                  
src                                └──────
typ                              └──────
doc                                └──────
txt                                └──────
par                                └──────
pid                                      
st                                └───────
457        ⟨λ ⟨f⟩, ⟨⟨f⟩, λ ⟨g⟩, (f.lt_le g).irrefl _⟩,
id                              └────┘
src  ─────┘  └┘ └─┘   └─┘ └┘ └─┘  └────┘ └────────────
typ  ─────┘  └┘└─┘   └─┘ └┘└─┘  └────┘ └────────────
doc  ─────┘  └┘ └─┘   └─┘ └┘ └─┘         └────────────
txt  ─────┘  └┘ └─┘   └─┘ └┘ └─┘         └────────────
par  ─────┘  └┘ └─┘   └─┘ └┘ └─┘         └────────────
pid  ─────┘  └┘ └─┘   └─┘ └┘ └─┘         └────────────
st   ──────────────────────────────────────────────────
458        λ ⟨⟨f⟩, h⟩, sum.rec_on f.lt_or_eq (λ g, ⟨g⟩)
id                   └────────┘  └───────┘
src  ─────┘ └┘  └─┘ └─┘└────────┘ └───────┘  └──┘  └──
typ  ─────┘ └┘ └─┘└─┘└────────┘ └───────┘  └──┘  └──
doc  ─────┘ └┘  └─┘ └─┘                      └──┘  └──
txt  ─────┘ └┘  └─┘ └─┘                      └──┘  └──
par  ─────┘ └┘  └─┘ └─┘                      └──┘  └──
pid  ─────┘ └┘  └─┘ └─┘                      └──┘  └──
st   ───────────────────────────────────────────────────
459         (λ g, (h ⟨initial_seg.of_iso g.symm⟩).elim)⟩,
id                    └────────────────┘  └───┘
src  ──────┘  └──┘   └────────────────┘ └───┘└───────┘
typ  ──────┘  └──┘   └────────────────┘ └───┘└───────┘
doc  ──────┘  └──┘   └────────────────┘      └───────┘
txt  ──────┘  └──┘                           └───────┘
par  ──────┘  └──┘                           └───────┘
pid  ──────┘  └──┘                           └───────┘
st   ──────────────────────────────────────────────────┘
460    le_antisymm := λ x b, show x ≤ b → b ≤ x → x = b, from
id                                         
src                                               
typ                                        
461      quotient.induction_on₂ x b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨h₁⟩ ⟨h₂⟩,
id       └────────────────────┘                             
src      └────────────────────┘
typ      └────────────────────┘                             
462      by exactI quot.sound ⟨initial_seg.antisymm h₁ h₂⟩ }
id                 └────────┘  └──────────────────┘ └┘ └┘
src         └─────┘└────────┘ └──────────────────┘    └┘
typ         └─────┘└────────┘ └──────────────────┘└┘└┘└┘
doc         └─────┘           └──────────────────┘    └┘
txt         └─────┘                                   └┘
par         └─────┘                                   └┘
pid                                                  
st         └──────────────────────────────────────────────┘
463  
464  def initial_seg_out {α β : ordinal} (h : α ≤ β) : initial_seg α.out.r β.out.r :=
id                              └─────┘             └─────────┘ └──┘└┘ └──┘└┘
src                             └─────┘               └─────────┘  └──┘└┘  └──┘└┘
typ                             └─────┘             └─────────┘ └──┘└┘ └──┘└┘
doc                             └─────┘                └─────────┘  └──┘    └──┘
465  begin
st   └─────
466    rw [←quotient.out_eq α, ←quotient.out_eq β] at h, revert h,
id          └─────────────┘    └─────────────┘ 
src    └───┘└─────────────┘ └─┘└─────────────┘ └────┘  └──────┘
typ    └───┘└─────────────┘└─┘└─────────────┘└────┘  └──────┘
doc    └───┘                └─┘                └────┘  └──────┘
txt    └───┘                └─┘                └────┘  └──────┘
par    └───┘                └─┘                └────┘  └──────┘
pid      └─┘                └─┘                └───┘        └┘
st   ───────────────────────┘└──────────────────┘└───┘└────────┘└─
467    cases quotient.out α, cases quotient.out β, exact classical.choice
id           └──────────┘         └──────────┘         └──────────────┘
src    └────┘└──────────┘   └────┘└──────────┘   └────┘└──────────────┘
typ    └────┘└──────────┘  └────┘└──────────┘  └────┘└──────────────┘
doc    └────┘└──────────┘   └────┘└──────────┘   └────┘                
txt    └────┘               └────┘               └────┘                
par    └────┘               └────┘               └────┘                
pid                                                                 
st   ─────────────────────┘└────────────────────┘└───────────────────────┘
468  end
st   └─┘
469  
470  def principal_seg_out {α β : ordinal} (h : α < β) : principal_seg α.out.r β.out.r :=
id                                └─────┘             └───────────┘ └──┘└┘ └──┘└┘
src                               └─────┘               └───────────┘  └──┘└┘  └──┘└┘
typ                               └─────┘             └───────────┘ └──┘└┘ └──┘└┘
doc                               └─────┘                               └──┘    └──┘
471  begin
st   └─────
472    rw [←quotient.out_eq α, ←quotient.out_eq β] at h, revert h,
id          └─────────────┘    └─────────────┘ 
src    └───┘└─────────────┘ └─┘└─────────────┘ └────┘  └──────┘
typ    └───┘└─────────────┘└─┘└─────────────┘└────┘  └──────┘
doc    └───┘                └─┘                └────┘  └──────┘
txt    └───┘                └─┘                └────┘  └──────┘
par    └───┘                └─┘                └────┘  └──────┘
pid      └─┘                └─┘                └───┘        └┘
st   ───────────────────────┘└──────────────────┘└───┘└────────┘└─
473    cases quotient.out α, cases quotient.out β, exact classical.choice
id           └──────────┘         └──────────┘         └──────────────┘
src    └────┘└──────────┘   └────┘└──────────┘   └────┘└──────────────┘
typ    └────┘└──────────┘  └────┘└──────────┘  └────┘└──────────────┘
doc    └────┘└──────────┘   └────┘└──────────┘   └────┘                
txt    └────┘               └────┘               └────┘                
par    └────┘               └────┘               └────┘                
pid                                                                 
st   ─────────────────────┘└────────────────────┘└───────────────────────┘
474  end
st   └─┘
475  
476  def order_iso_out {α β : ordinal} (h : α = β) : order_iso α.out.r β.out.r :=
id                            └─────┘             └───────┘ └──┘└┘ └──┘└┘
src                           └─────┘               └───────┘  └──┘└┘  └──┘└┘
typ                           └─────┘             └───────┘ └──┘└┘ └──┘└┘
doc                           └─────┘                └───────┘  └──┘    └──┘
477  begin
st   └─────
478    rw [←quotient.out_eq α, ←quotient.out_eq β] at h, revert h,
id          └─────────────┘    └─────────────┘ 
src    └───┘└─────────────┘ └─┘└─────────────┘ └────┘  └──────┘
typ    └───┘└─────────────┘└─┘└─────────────┘└────┘  └──────┘
doc    └───┘                └─┘                └────┘  └──────┘
txt    └───┘                └─┘                └────┘  └──────┘
par    └───┘                └─┘                └────┘  └──────┘
pid      └─┘                └─┘                └───┘        └┘
st   ───────────────────────┘└──────────────────┘└───┘└────────┘└─
479    cases quotient.out α, cases quotient.out β, exact classical.choice ∘ quotient.exact
id           └──────────┘         └──────────┘         └──────────────┘  └────────────┘
src    └────┘└──────────┘   └────┘└──────────┘   └────┘└──────────────┘└────────────┘
typ    └────┘└──────────┘  └────┘└──────────┘  └────┘└──────────────┘└────────────┘
doc    └────┘└──────────┘   └────┘└──────────┘   └────┘                               
txt    └────┘               └────┘               └────┘                               
par    └────┘               └────┘               └────┘                               
pid                                                                                
st   ─────────────────────┘└────────────────────┘└────────────────────────────────────────┘
480  end
st   └─┘
481  
482  theorem typein_lt_type (r : α → α → Prop) [is_well_order α r]
id                                            └───────────┘  
src                                             └───────────┘
typ                                           └───────────┘  
doc                                             └───────────┘
483    (a : α) : typein r a < type r :=
id              └────┘    └──┘ 
src              └────┘      └──┘
typ             └────┘    └──┘ 
doc              └────┘       └──┘
484  ⟨principal_seg.of_element _ _⟩
id    └──────────────────────┘
src   └──────────────────────┘
typ   └──────────────────────┘
doc   └──────────────────────┘
485  
486  @[simp] theorem typein_top {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                             
typ                                                            
doc    └──┘
487    [is_well_order α r] [is_well_order β s] (f : r ≺i s) :
id      └───────────┘     └───────────┘          └┘ 
src     └───────────┘       └───────────┘             └┘
typ     └───────────┘     └───────────┘          └┘ 
doc     └───────────┘       └───────────┘
488    typein s f.top = type r :=
id     └────┘  └──┘  └──┘ 
src    └────┘    └──┘  └──┘
typ    └────┘  └──┘  └──┘ 
doc    └────┘           └──┘
489  eq.symm $ quot.sound ⟨order_iso.of_surjective
id   └─────┘   └────────┘  └─────────────────────┘
src  └─────┘   └────────┘  └─────────────────────┘
typ  └─────┘   └────────┘  └─────────────────────┘
490    (order_embedding.cod_restrict _ f f.lt_top)
id      └──────────────────────────┘    └─────┘
src     └──────────────────────────┘      └─────┘
typ     └──────────────────────────┘    └─────┘
doc     └──────────────────────────┘
491    (λ ⟨a, h⟩, by rcases f.down'.1 h with ⟨b, rfl⟩; exact ⟨b, rfl⟩)⟩
id                         └─────┘                            └─┘
src                  └─────┘└─────┘└─┘ └────────────┘  └────┘  └┘└─┘
typ                 └─────┘└─────┘└─┘└────────────┘  └────┘ └┘└─┘
doc                  └─────┘       └─┘ └────────────┘  └────┘  └┘   
txt                  └─────┘       └─┘ └────────────┘  └────┘  └┘   
par                  └─────┘       └─┘ └────────────┘  └────┘  └┘   
pid                               └─┘ └────────────┘         └┘   
st                  └───────────────────────────────────────────────┘
492  
493  @[simp] theorem typein_apply {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                               
typ                                                              
doc    └──┘
494    [is_well_order α r] [is_well_order β s] (f : r ≼i s) (a : α) :
id      └───────────┘     └───────────┘          └┘        
src     └───────────┘       └───────────┘             └┘
typ     └───────────┘     └───────────┘          └┘        
doc     └───────────┘       └───────────┘             └┘
495    ordinal.typein s (f a) = ordinal.typein r a :=
id     └────────────┘       └────────────┘  
src    └────────────┘          └────────────┘
typ    └────────────┘       └────────────┘  
doc    └────────────┘           └────────────┘
496  eq.symm $ quotient.sound ⟨order_iso.of_surjective
id   └─────┘   └────────────┘  └─────────────────────┘
src  └─────┘   └────────────┘  └─────────────────────┘
typ  └─────┘   └────────────┘  └─────────────────────┘
497    (order_embedding.cod_restrict _
id      └──────────────────────────┘
src     └──────────────────────────┘
typ     └──────────────────────────┘
doc     └──────────────────────────┘
498      ((subrel.order_embedding _ _).trans f)
id         └────────────────────┘     └───┘  
src        └────────────────────┘     └───┘
typ        └────────────────────┘     └───┘  
499      (λ ⟨x, h⟩, by rw [order_embedding.trans_apply]; exact f.to_order_embedding.ord'.1 h))
id                        └─────────────────────────┘         └───────────────────────┘   
src                    └──┘└─────────────────────────┘  └────┘└───────────────────────┘└─┘
typ                   └──┘└─────────────────────────┘  └────┘└───────────────────────┘└─┘
doc                    └──┘                             └────┘                         └─┘
txt                    └──┘                             └────┘                         └─┘
par                    └──┘                             └────┘                         └─┘
pid                      └┘                                                           └─┘
st                    └──────────────────────────────┘└───────────────────────────────────┘
500    (λ ⟨y, h⟩, by rcases f.init' h with ⟨a, rfl⟩;
id                         └─────┘ 
src                  └─────┘└─────┘ └────────────┘
typ                 └─────┘└─────┘└────────────┘
doc                  └─────┘        └────────────┘
txt                  └─────┘        └────────────┘
par                  └─────┘        └────────────┘
pid                                └────────────┘
st                  └────────────────────────────────
501      exact ⟨⟨a, f.to_order_embedding.ord'.2 h⟩, subtype.eq $ order_embedding.trans_apply _ _ _⟩)⟩
id                 └───────────────────────┘      └────────┘   └─────────────────────────┘
src      └────┘   └┘└───────────────────────┘└─┘ └─┘└────────┘ └─────────────────────────┘└─────┘
typ      └────┘  └┘└───────────────────────┘└─┘└─┘└────────┘ └─────────────────────────┘└─────┘
doc      └────┘   └┘                         └─┘ └─┘                                      └─────┘
txt      └────┘   └┘                         └─┘ └─┘                                      └─────┘
par      └────┘   └┘                         └─┘ └─┘                                      └─────┘
pid              └┘                         └─┘ └─┘                                      └─────┘
st   ─────────────────────────────────────────────────────────────────────────────────────────────┘
502  
503  @[simp] theorem typein_lt_typein (r : α → α → Prop) [is_well_order α r]
id                                                      └───────────┘  
src                                                       └───────────┘
typ                                                     └───────────┘  
doc    └──┘                                               └───────────┘
504    {a b : α} : typein r a < typein r b ↔ r a b :=
id                └────┘    └────┘      
src                └────┘      └────┘     
typ               └────┘    └────┘      
doc                └────┘       └────┘
505  ⟨λ ⟨f⟩, begin
id      
typ     
st           └─────
506    have : f.top.1 = a,
id            └───┘    
src    └─────┘└───┘└─┘
typ    └─────┘└───┘└─┘
doc    └─────┘     └─┘ 
txt    └─────┘     └─┘ 
par    └─────┘     └─┘ 
pid    └───┘└┘     └─┘ 
st   ───────────────────┘└─
507    { let f' := principal_seg.of_element r a,
id                 └──────────────────────┘  
src      └────────┘└──────────────────────┘ 
typ      └────────┘└──────────────────────┘
doc      └────────┘└──────────────────────┘ 
txt      └────────┘                         
par      └────────┘                         
pid      └────┘└─┘                         
st   ───┘└────────────────────────────────────┘└─
508      let g' := f.trans (principal_seg.of_element r b),
id                 └─────┘  └──────────────────────┘  
src      └────────┘└─────┘ └──────────────────────┘  
typ      └────────┘└─────┘ └──────────────────────┘
doc      └────────┘        └──────────────────────┘  
txt      └────────┘                                  
par      └────────┘                                  
pid      └────┘└─┘                                  
st   ───────────────────────────────────────────────────┘└─
509      have : g'.top = f'.top, {rw subsingleton.elim f' g'},
id              └────┘   └────┘      └───────────────┘ └┘ └┘
src      └─────┘└────┘ └────┘   └─┘└───────────────┘  
typ      └─────┘└────┘ └────┘   └─┘└───────────────┘└┘└┘
doc      └─────┘                └─┘                   
txt      └─────┘                └─┘                   
par      └─────┘                └─┘                   
pid      └───┘└┘                                     
st   ─────────────────────────┘└────┘└───────────────┘└────┘└┘
510      exact this },
id             └──┘
src      └────┘    
typ      └────┘└──┘
doc      └────┘    
txt      └────┘    
par      └────┘    
pid               
st   ──────────────┘└┘
511    rw ← this, exact f.top.2
id          └──┘        └───┘
src    └───┘      └────┘└───┘└─┘
typ    └───┘└──┘  └────┘└───┘└─┘
doc    └───┘      └────┘     └─┘
txt    └───┘      └────┘     └─┘
par    └───┘      └────┘     └─┘
pid      └─┘                └─┘
st   ──────────┘└──────────────┘
512  end, λ h, ⟨principal_seg.cod_restrict _
id             └────────────────────────┘
src             └────────────────────────┘
typ            └────────────────────────┘
doc             └────────────────────────┘
st   └─┘
513    (principal_seg.of_element r a)
id      └──────────────────────┘  
src     └──────────────────────┘
typ     └──────────────────────┘  
doc     └──────────────────────┘
514    (λ x, @trans _ r _ _ _ _ x.2 h) h⟩⟩
id           └───┘                
src           └───┘              
typ          └───┘                
515  
516  theorem typein_surj (r : α → α → Prop) [is_well_order α r]
id                                         └───────────┘  
src                                          └───────────┘
typ                                        └───────────┘  
doc                                          └───────────┘
517    {o} (h : o < type r) : ∃ a, typein r a = o :=
id                └──┘       └────┘    
src                └──┘         └────┘     
typ               └──┘       └────┘    
doc                 └──┘           └────┘
518  induction_on o (λ β s _ ⟨f⟩, by exactI ⟨f.top, typein_top _⟩) h
id   └──────────┘                       └───┘  └────────┘     
src  └──────────┘                    └─────┘ └───┘└┘└────────┘└─┘
typ  └──────────┘               └─────┘ └───┘└┘└────────┘└─┘  
doc                                  └─────┘      └┘          └─┘
txt                                  └─────┘      └┘          └─┘
par                                  └─────┘      └┘          └─┘
pid                                              └┘          └─┘
st                                  └───────────────────────────┘
519  
520  lemma injective_typein (r : α → α → Prop) [is_well_order α r] : injective (typein r) :=
id                                            └───────────┘      └───────┘  └────┘ 
src                                             └───────────┘        └───────┘  └────┘
typ                                           └───────────┘      └───────┘  └────┘ 
doc                                             └───────────┘                   └────┘
521  injective_of_increasing r (<) (typein r) (λ x y, (typein_lt_typein r).2)
id   └─────────────────────┘      └────┘          └──────────────┘  
src  └─────────────────────┘       └────┘             └──────────────┘   
typ  └─────────────────────┘      └────┘          └──────────────┘  
doc  └─────────────────────┘        └────┘
522  
523  theorem typein_inj (r : α → α → Prop) [is_well_order α r]
id                                        └───────────┘  
src                                         └───────────┘
typ                                       └───────────┘  
doc                                         └───────────┘
524    {a b} : typein r a = typein r b ↔ a = b :=
id             └────┘    └────┘      
src            └────┘      └────┘        
typ            └────┘    └────┘      
doc            └────┘       └────┘
525  injective.eq_iff (injective_typein r)
id   └──────────────┘  └──────────────┘ 
src  └──────────────┘  └──────────────┘
typ  └──────────────┘  └──────────────┘ 
526  
527  /-- `enum r o h` is the `o`-th element of `α` ordered by `r`.
528    That is, `enum` maps an initial segment of the ordinals, those
529    less than the order type of `r`, to the elements of `α`. -/
530  def enum (r : α → α → Prop) [is_well_order α r] (o) : o < type r → α :=
id                              └───────────┘            └──┘    
src                               └───────────┘               └──┘
typ                             └───────────┘            └──┘    
doc                               └───────────┘                └──┘
531  quot.rec_on o (λ ⟨β, s, _⟩ h, (classical.choice h).top) $
id   └─────────┘                 └──────────────┘  └─┘
src  └─────────┘                    └──────────────┘   └─┘
typ  └─────────┘                 └──────────────┘  └─┘
532  λ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨h⟩, begin
id                       
typ                      
st                              └─────
533    resetI, refine funext (λ (H₂ : type t < type r), _),
id                    └────┘                 └──┘ 
src    └────┘  └─────┘└────┘  └─────┘     └──┘ └───┘
typ    └────┘  └─────┘└────┘  └─────┘    └──┘└───┘
doc    └────┘  └─────┘        └─────┘      └──┘ └───┘
txt    └────┘  └─────┘        └─────┘           └───┘
par    └────┘  └─────┘        └─────┘           └───┘
pid                          └─────┘           └───┘
st   ────────────────────────────────────────────────────┘└─
534    have H₁ : type s < type r, {rwa type_eq.2 ⟨h⟩},
id                      └──┘        └─────┘    
src    └────────┘      └──┘    └──┘└─────┘└─┘  
typ    └────────┘    └──┘   └──┘└─────┘└─┘ 
doc    └────────┘      └──┘    └──┘       └─┘  
txt    └────────┘              └──┘       └─┘  
par    └────────┘              └──┘       └─┘  
pid    └─────┘└─┘                        └─┘  
st   ──────────────────────────┘└─────┘└─────┘└────┘└┘
535    have : ∀ {o e} (H : o < type r), @@eq.rec
id                                       └────┘
src    └─────┘ └──────────┘          └────┘
typ    └─────┘ └──────────┘         └────┘
doc    └─────┘ └──────────┘                
txt    └─────┘ └──────────┘                
par    └─────┘ └──────────┘                
pid    └───┘└┘ └──────────┘                
st   ────────────────────────────────────────────
536     (λ (o : ordinal), o < type r → α)
id              └─────┘               
src  ──┘  └────┘└─────┘└─┘         └─
typ  ──┘  └────┘└─────┘└─┘       └─
doc  ──┘  └────┘└─────┘└─┘         └─
txt  ──┘  └────┘       └─┘         └─
par  ──┘  └────┘       └─┘         └─
pid  ──┘  └────┘       └─┘         └─
st   ─────────────────────────────────────
537     (λ (h : type s < type r), (classical.choice h).top)
id                      └──┘ 
src  ──┘  └────┘      └──┘ └─┘                  └──────
typ  ──┘  └────┘     └──┘└─┘                  └──────
doc  ──┘  └────┘      └──┘ └─┘                  └──────
txt  ──┘  └────┘           └─┘                  └──────
par  ──┘  └────┘           └─┘                  └──────
pid  ──┘  └────┘           └─┘                  └──────
st   ───────────────────────────────────────────────────────
538       e H = (classical.choice H₁).top, {intros, subst e},
id              └──────────────┘ └┘                      
src  ────┘   └──────────────┘  └───┘   └────┘  └────┘
typ  ────┘   └──────────────┘└┘└───┘   └────┘  └────┘
doc  ────┘                      └───┘   └────┘  └────┘
txt  ────┘                      └───┘   └────┘  └────┘
par  ────┘                      └───┘   └────┘  └────┘
pid  ────┘                      └──┘                
st   ───────────────────────────────────┘└───────┘└───────┘└┘
539    exact (this H₂).trans (principal_seg.top_eq h
id            └──┘            └──────────────────┘ 
src    └────┘       └──────┘ └──────────────────┘ 
typ    └────┘ └──┘  └──────┘ └──────────────────┘
doc    └────┘       └──────┘                      
txt    └────┘       └──────┘                      
par    └────┘       └──────┘                      
pid                └──────┘                      
st   ────────────────────────────────────────────────
540      (classical.choice H₁) (classical.choice H₂))
id                         └┘   └──────────────┘ └┘
src  ───┘                   └┘ └──────────────┘  └─┘
typ  ───┘                 └┘└┘ └──────────────┘└┘└─┘
doc  ───┘                   └┘                   └─┘
txt  ───┘                   └┘                   └─┘
par  ───┘                   └┘                   └─┘
pid  ───┘                   └┘                   └┘
st   ────────────────────────────────────────────────┘
541  end
st   └─┘
542  
543  theorem enum_type {α β} {r : α → α → Prop} {s : β → β → Prop}
id                                                    
typ                                                   
544    [is_well_order α r] [is_well_order β s] (f : s ≺i r)
id      └───────────┘     └───────────┘          └┘ 
src     └───────────┘       └───────────┘             └┘
typ     └───────────┘     └───────────┘          └┘ 
doc     └───────────┘       └───────────┘
545    {h : type s < type r} : enum r (type s) h = f.top :=
id          └──┘   └──┘     └──┘   └──┘     └──┘
src         └──┘    └──┘      └──┘    └──┘        └──┘
typ         └──┘   └──┘     └──┘   └──┘     └──┘
doc         └──┘     └──┘      └──┘    └──┘
546  principal_seg.top_eq (order_iso.refl _) _ _
id   └──────────────────┘  └────────────┘
src  └──────────────────┘  └────────────┘
typ  └──────────────────┘  └────────────┘
547  
548  @[simp] theorem enum_typein (r : α → α → Prop) [is_well_order α r] (a : α)
id                                                 └───────────┘         
src                                                  └───────────┘
typ                                                └───────────┘         
doc    └──┘                                          └───────────┘
549    {h : typein r a < type r} : enum r (typein r a) h = a :=
id          └────┘    └──┘     └──┘   └────┘      
src         └────┘      └──┘      └──┘    └────┘        
typ         └────┘    └──┘     └──┘   └────┘      
doc         └────┘       └──┘      └──┘    └────┘
550  enum_type (principal_seg.of_element r a)
id   └───────┘  └──────────────────────┘  
src  └───────┘  └──────────────────────┘
typ  └───────┘  └──────────────────────┘  
doc             └──────────────────────┘
551  
552  @[simp] theorem typein_enum (r : α → α → Prop) [is_well_order α r]
id                                                 └───────────┘  
src                                                  └───────────┘
typ                                                └───────────┘  
doc    └──┘                                          └───────────┘
553    {o} (h : o < type r) : typein r (enum r o h) = o :=
id                └──┘     └────┘   └──┘      
src                └──┘      └────┘    └──┘        
typ               └──┘     └────┘   └──┘      
doc                 └──┘      └────┘    └──┘
554  let ⟨a, e⟩ := typein_surj r h in
id   └─┘           └─────────┘  
src                └─────────┘
typ  └─┘           └─────────┘  
555  by clear _let_match; subst e; rw enum_typein
id                                   └─────────┘
src     └──────────────┘  └────┘   └─┘└─────────┘
typ     └──────────────┘  └────┘  └─┘└─────────┘
doc     └──────────────┘  └────┘   └─┘           
txt     └──────────────┘  └────┘   └─┘           
par     └──────────────┘  └────┘   └─┘           
pid          └─────────┘                       
st     └─────────────────────────────┘└─────────┘
556  
src  
typ  
doc  
txt  
par  
pid  
st   
557  def typein_iso (r : α → α → Prop) [is_well_order α r] : r ≃o subrel (<) (< type r) :=
id                                    └───────────┘       └┘ └────┘      └──┘ 
src                                     └───────────┘          └┘ └────┘      └──┘
typ                                   └───────────┘       └┘ └────┘      └──┘ 
doc                                     └───────────┘          └┘ └────┘        └──┘
558  ⟨⟨λ x, ⟨typein r x, typein_lt_type r x⟩, λ x, enum r x.1 x.2, λ y, enum_typein r y,
id          └────┘    └────────────┘         └──┘           └─────────┘  
src          └────┘      └────────────┘            └──┘               └─────────┘
typ         └────┘    └────────────┘         └──┘           └─────────┘  
doc          └────┘                                └──┘
559   λ ⟨y, hy⟩, subtype.eq (typein_enum r hy)⟩,
id         └┘   └────────┘  └─────────┘ 
src              └────────┘  └─────────┘
typ        └┘   └────────┘  └─────────┘ 
560    λ a b, (typein_lt_typein r).symm⟩
id           └──────────────┘  └──┘
src            └──────────────┘   └──┘
typ          └──────────────┘  └──┘
561  
562  theorem enum_lt {r : α → α → Prop} [is_well_order α r]
id                                     └───────────┘  
src                                      └───────────┘
typ                                    └───────────┘  
doc                                      └───────────┘
563    {o₁ o₂ : ordinal} (h₁ : o₁ < type r) (h₂ : o₂ < type r) :
id              └─────┘        └┘  └──┘         └┘  └──┘ 
src             └─────┘            └──┘              └──┘
typ             └─────┘        └┘  └──┘         └┘  └──┘ 
doc             └─────┘             └──┘               └──┘
564    r (enum r o₁ h₁) (enum r o₂ h₂) ↔ o₁ < o₂ :=
id       └──┘  └┘ └┘   └──┘  └┘ └┘   └┘  └┘
src       └──┘           └──┘              
typ      └──┘  └┘ └┘   └──┘  └┘ └┘   └┘  └┘
doc       └──┘           └──┘
565  by rw [← typein_lt_typein r, typein_enum, typein_enum]
id            └──────────────┘   └─────────┘  └─────────┘
src     └────┘└──────────────┘ └┘└─────────┘└┘└─────────┘└─
typ     └────┘└──────────────┘└┘└─────────┘└┘└─────────┘└─
doc     └────┘                 └┘           └┘           └─
txt     └────┘                 └┘           └┘           └─
par     └────┘                 └┘           └┘           └─
pid       └──┘                 └┘           └┘           
st     └───────────────────────┘└───────────┘└───────────┘
566  
src  
typ  
doc  
txt  
par  
pid  
st   
567  lemma order_iso_enum' {α β : Type u} {r : α → α → Prop} {s : β → β → Prop}
id                                                                 
typ                                                                
568    [is_well_order α r] [is_well_order β s]
id      └───────────┘     └───────────┘  
src     └───────────┘       └───────────┘
typ     └───────────┘     └───────────┘  
doc     └───────────┘       └───────────┘
569    (f : order_iso r s) (o : ordinal) : ∀(hr : o < type r) (hs : o < type s),
id          └───────┘         └─────┘             └──┘           └──┘ 
src         └───────┘           └─────┘              └──┘             └──┘
typ         └───────┘         └─────┘             └──┘           └──┘ 
doc         └───────┘           └─────┘               └──┘              └──┘
570    f (enum r o hr) = enum s o hs :=
id       └──┘   └┘   └──┘   └┘
src       └──┘          └──┘
typ      └──┘   └┘   └──┘   └┘
doc       └──┘           └──┘
571  begin
st   └─────
572    refine induction_on o _, rintros γ t wo ⟨g⟩ ⟨h⟩,
id            └──────────┘ 
src    └─────┘└──────────┘ └┘  └────────────────────┘
typ    └─────┘└──────────┘└┘  └────────────────────┘
doc    └─────┘             └┘  └────────────────────┘
txt    └─────┘             └┘  └────────────────────┘
par    └─────┘             └┘  └────────────────────┘
pid                       └┘         └─────────────┘
st   ────────────────────────┘└──────────────────────┘└─
573    resetI, rw [enum_type g, enum_type (principal_seg.lt_equiv g f)], refl
id                 └───────┘   └───────┘  └────────────────────┘  
src    └────┘  └──┘└───────┘ └┘└───────┘ └────────────────────┘  └┘  └───┘
typ    └────┘  └──┘└───────┘└┘└───────┘ └────────────────────┘└┘  └───┘
doc    └────┘  └──┘          └┘                                  └┘  └───┘
txt    └────┘  └──┘          └┘                                  └┘  └───┘
par    └────┘  └──┘          └┘                                  └┘  └───┘
pid              └┘          └┘                                  └┘      
st   ────────────────────────┘└──────────────────────────────────────┘└──────┘
574  end
st   └─┘
575  
576  lemma order_iso_enum {α β : Type u} {r : α → α → Prop} {s : β → β → Prop}
id                                                                
typ                                                               
577    [is_well_order α r] [is_well_order β s]
id      └───────────┘     └───────────┘  
src     └───────────┘       └───────────┘
typ     └───────────┘     └───────────┘  
doc     └───────────┘       └───────────┘
578    (f : order_iso r s) (o : ordinal) (hr : o < type r) :
id          └───────┘         └─────┘          └──┘ 
src         └───────┘           └─────┘           └──┘
typ         └───────┘         └─────┘          └──┘ 
doc         └───────┘           └─────┘            └──┘
579    f (enum r o hr) =
id       └──┘   └┘  
src       └──┘         
typ      └──┘   └┘  
doc       └──┘
580    enum s o (by {convert hr using 1, apply quotient.sound, exact ⟨f.symm⟩ }) :=
id     └──┘                └┘                └────────────┘         └────┘
src    └──┘          └──────┘  └──────┘  └────┘└────────────┘  └────┘ └────┘└┘
typ    └──┘        └──────┘└┘└──────┘  └────┘└────────────┘  └────┘ └────┘└┘
doc    └──┘          └──────┘  └──────┘  └────┘                └────┘       └┘
txt                  └──────┘  └──────┘  └────┘                └────┘       └┘
par                  └──────┘  └──────┘  └────┘                └────┘       └┘
pid                           └─────┘                                   
st                 └──────────────────┘└────────────────────┘└───────────────┘└┘
581  order_iso_enum' _ _ _ _
id   └─────────────┘
src  └─────────────┘
typ  └─────────────┘
582  
583  theorem wf : @well_founded ordinal (<) :=
id                 └──────────┘ └─────┘ 
src                └──────────┘ └─────┘ 
typ                └──────────┘ └─────┘ 
doc                             └─────┘
584  ⟨λ a, induction_on a $ λ α r wo, by exactI
id        └──────────┘        └┘
src        └──────────┘                  └─────┘
typ       └──────────┘        └┘     └─────┘
doc                                      └─────┘
txt                                      └─────┘
par                                      └─────┘
pid                                            
st                                      └───────
585  suffices ∀ a, acc (<) (typein r a), from
id                 └─┘     └────┘
src           └┘ └─┘└─┘ └────┘  └──────┘
typ           └┘ └─┘└─┘ └────┘  └──────┘
doc           └┘     └─┘ └────┘  └──────┘
txt           └┘     └─┘         └──────┘
par           └┘     └─┘         └──────┘
pid           └┘     └─┘         └──────┘
st   ─────────────────────────────────────────
586  ⟨_, λ o h, let ⟨a, e⟩ := typein_surj r h in e ▸ this a⟩,
id                          └─────────┘         
src   └─┘ └────┘     └┘ └───┘└─────────┘  └──┘      └─┘
typ   └─┘ └────┘    └┘└───┘└─────────┘ └──┘      └─┘
doc   └─┘ └────┘     └┘ └───┘             └──┘       └─┘
txt   └─┘ └────┘     └┘ └───┘             └──┘       └─┘
par   └─┘ └────┘     └┘ └───┘             └──┘       └─┘
pid   └─┘ └────┘     └┘ └───┘             └──┘       └─┘
st   ─────────────────────────────────────────────────────────
587  λ a, acc.rec_on (wo.wf.apply a) $ λ x H IH, ⟨_, λ o h, begin
id        └────────┘  └─────────┘
src   └──┘└────────┘ └─────────┘ └┘  └───────┘ └─┘ └────┘     
typ   └──┘└────────┘ └─────────┘ └┘  └───────┘ └─┘ └────┘     
doc   └──┘                       └┘  └───────┘ └─┘ └────┘     
txt   └──┘                       └┘  └───────┘ └─┘ └────┘     
par   └──┘                       └┘  └───────┘ └─┘ └────┘     
pid   └──┘                       └┘  └───────┘ └─┘ └────┘     
st   ──────────────────────────────────────────────────────┘└─────
588    rcases typein_surj r (lt_trans h (typein_lt_type r _)) with ⟨b, rfl⟩,
id            └─────────┘    └──────┘   └────────────┘ 
src  ─┘└─────┘└─────────┘  └──────┘  └────────────┘ └────────────────┘└─
typ  ─┘└─────┘└─────────┘  └──────┘ └────────────┘└────────────────┘└─
doc  ─┘└─────┘                                      └────────────────┘└─
txt  ─┘└─────┘                                      └────────────────┘└─
par  ─┘└─────┘                                      └────────────────┘└─
pid  ────────┘                                      └───────────────────
st   ─────────────────────────────────────────────────────────────────────┘└─
589    exact IH _ ((typein_lt_typein r).1 h)
id           └┘     └──────────────┘     
src  ─┘└────┘  └─┘  └──────────────┘ └──┘ └┘
typ  ───────┘└┘└─┘  └──────────────┘└──┘└─
doc  ─┘└────┘  └─┘                   └──┘ └┘
txt  ─┘└────┘  └─┘                   └──┘ └┘
par  ───────┘  └─┘                   └──┘ └─
pid  ───────┘  └─┘                   └──┘ └─
st   ───────────────────────────────────────┘
590  end⟩⟩
src  └──┘
typ  ───┘
doc  └──┘
txt  └──┘
par  ───┘
pid  ───┘
st   └─┘
591  
592  instance : has_well_founded ordinal := ⟨(<), wf⟩
id              └──────────────┘ └─────┘         └┘
src             └──────────────┘ └─────┘         └┘
typ             └──────────────┘ └─────┘         └┘
doc                              └─────┘
593  
594  /-- The cardinal of an ordinal is the cardinal of any
595    set with that order type. -/
596  def card (o : ordinal) : cardinal :=
id                 └─────┘    └──────┘
src                └─────┘    └──────┘
typ                └─────┘    └──────┘
doc                └─────┘    └──────┘
597  quot.lift_on o (λ ⟨α, r, _⟩, mk α) $
id   └──────────┘              └┘
src  └──────────┘                 └┘
typ  └──────────┘              └┘
doc                               └┘
598  λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨e⟩, quotient.sound ⟨e.to_equiv⟩
id                          └────────────┘   └───────┘
src                             └────────────┘   └───────┘
typ                         └────────────┘   └───────┘
599  
600  @[simp] theorem card_type (r : α → α → Prop) [is_well_order α r] :
id                                               └───────────┘  
src                                                └───────────┘
typ                                              └───────────┘  
doc    └──┘                                        └───────────┘
601    card (type r) = mk α := rfl
id     └──┘  └──┘    └┘     └─┘
src    └──┘  └──┘     └┘      └─┘
typ    └──┘  └──┘    └┘     └─┘
doc    └──┘  └──┘      └┘
602  
603  lemma card_typein {r : α → α → Prop} [wo : is_well_order α r] (x : α) :
id                                            └───────────┘         
src                                             └───────────┘
typ                                           └───────────┘         
doc                                             └───────────┘
604    mk {y // r y x} = (typein r x).card := rfl
id     └┘           └────┘   └──┘     └─┘
src    └┘               └────┘     └──┘     └─┘
typ    └┘           └────┘   └──┘     └─┘
doc    └┘                 └────┘     └──┘
605  
606  theorem card_le_card {o₁ o₂ : ordinal} : o₁ ≤ o₂ → card o₁ ≤ card o₂ :=
id                                 └─────┘    └┘  └┘   └──┘ └┘  └──┘ └┘
src                                └─────┘             └──┘     └──┘
typ                                └─────┘    └┘  └┘   └──┘ └┘  └──┘ └┘
doc                                └─────┘              └──┘      └──┘
607  induction_on o₁ $ λ α r _, induction_on o₂ $ λ β s _ ⟨⟨⟨f, _⟩, _⟩⟩, ⟨f⟩
id   └──────────┘ └┘         └──────────┘ └┘          
src  └──────────┘               └──────────┘
typ  └──────────┘ └┘         └──────────┘ └┘          
608  
609  instance : has_zero ordinal :=
id              └──────┘ └─────┘
src             └──────┘ └─────┘
typ             └──────┘ └─────┘
doc                      └─────┘
610  ⟨⟦⟨pempty, empty_relation, by apply_instance⟩⟧⟩
id     └────┘  └────────────┘                    
src    └────┘  └────────────┘     └────────────┘ 
typ    └────┘  └────────────┘     └────────────┘ 
doc     └────┘                     └────────────┘
txt                                └────────────┘
par                                └────────────┘
st                                └─────────────┘
611  
612  instance : inhabited ordinal := ⟨0⟩
id              └───────┘ └─────┘
src             └───────┘ └─────┘
typ             └───────┘ └─────┘
doc                       └─────┘
613  
614  theorem zero_eq_type_empty : 0 = @type empty empty_relation _ :=
id                                    └──┘ └───┘ └────────────┘
src                                   └──┘ └───┘ └────────────┘
typ                                   └──┘ └───┘ └────────────┘
doc                                    └──┘
615  quotient.sound ⟨⟨empty_equiv_pempty.symm, λ _ _, iff.rfl⟩⟩
id   └────────────┘   └────────────────┘└───┘       └─────┘
src  └────────────┘   └────────────────┘└───┘         └─────┘
typ  └────────────┘   └────────────────┘└───┘       └─────┘
616  
617  @[simp] theorem card_zero : card 0 = 0 := rfl
id                               └──┘         └─┘
src                              └──┘         └─┘
typ                              └──┘         └─┘
doc    └──┘                      └──┘
618  
619  theorem zero_le (o : ordinal) : 0 ≤ o :=
id                        └─────┘       
src                       └─────┘      
typ                       └─────┘       
doc                       └─────┘
620  induction_on o $ λ α r _,
id   └──────────┘        
src  └──────────┘
typ  └──────────┘        
621  ⟨⟨⟨embedding.of_not_nonempty $ λ ⟨a⟩, a.elim,
id      └───────────────────────┘         └───┘
src     └───────────────────────┘           └───┘
typ     └───────────────────────┘         └───┘
622    λ a, a.elim⟩, λ a, a.elim⟩⟩
id         └───┘       └───┘
src          └───┘         └───┘
typ        └───┘       └───┘
623  
624  @[simp] theorem le_zero {o : ordinal} : o ≤ 0 ↔ o = 0 :=
id                                └─────┘          
src                               └─────┘            
typ                               └─────┘          
doc    └──┘                       └─────┘
625  by simp only [le_antisymm_iff, zero_le, and_true]
id                 └─────────────┘  └─────┘  └──────┘
src     └─────────┘└─────────────┘└┘└─────┘└┘└──────┘└─
typ     └─────────┘└─────────────┘└┘└─────┘└┘└──────┘└─
doc     └─────────┘               └┘       └┘        └─
txt     └─────────┘               └┘       └┘        └─
par     └─────────┘               └┘       └┘        └─
pid         └──┘└┘               └┘       └┘        
st     └───────────────────────────────────────────────
626  
src  
typ  
doc  
txt  
par  
pid  
st   
627  theorem pos_iff_ne_zero {o : ordinal} : 0 < o ↔ o ≠ 0 :=
id                                └─────┘          
src                               └─────┘            
typ                               └─────┘          
doc                               └─────┘
628  by simp only [lt_iff_le_and_ne, zero_le, true_and, ne.def, eq_comm]
id                 └──────────────┘  └─────┘  └──────┘  └────┘  └─────┘
src     └─────────┘└──────────────┘└┘└─────┘└┘└──────┘└┘└────┘└┘└─────┘└─
typ     └─────────┘└──────────────┘└┘└─────┘└┘└──────┘└┘└────┘└┘└─────┘└─
doc     └─────────┘                └┘       └┘        └┘      └┘       └─
txt     └─────────┘                └┘       └┘        └┘      └┘       └─
par     └─────────┘                └┘       └┘        └┘      └┘       └─
pid         └──┘└┘                └┘       └┘        └┘      └┘       
st     └─────────────────────────────────────────────────────────────────
629  
src  
typ  
doc  
txt  
par  
pid  
st   
630  instance : has_one ordinal :=
id              └─────┘ └─────┘
src             └─────┘ └─────┘
typ             └─────┘ └─────┘
doc                     └─────┘
631  ⟨⟦⟨punit, empty_relation, by apply_instance⟩⟧⟩
id     └───┘  └────────────┘                    
src    └───┘  └────────────┘     └────────────┘ 
typ    └───┘  └────────────┘     └────────────┘ 
doc                               └────────────┘
txt                               └────────────┘
par                               └────────────┘
st                               └─────────────┘
632  
633  theorem one_eq_type_unit : 1 = @type unit empty_relation _ :=
id                                  └──┘ └──┘ └────────────┘
src                                 └──┘ └──┘ └────────────┘
typ                                 └──┘ └──┘ └────────────┘
doc                                  └──┘ └──┘
634  quotient.sound ⟨⟨punit_equiv_punit, λ _ _, iff.rfl⟩⟩
id   └────────────┘   └───────────────┘       └─────┘
src  └────────────┘   └───────────────┘         └─────┘
typ  └────────────┘   └───────────────┘       └─────┘
635  
636  @[simp] theorem card_one : card 1 = 1 := rfl
id                              └──┘         └─┘
src                             └──┘         └─┘
typ                             └──┘         └─┘
doc    └──┘                     └──┘
637  
638  instance : has_add ordinal.{u} :=
id              └─────┘ └─────┘
src             └─────┘ └─────┘
typ             └─────┘ └─────┘
doc                     └─────┘
639  ⟨λo₁ o₂, quotient.lift_on₂ o₁ o₂
id     └┘ └┘  └───────────────┘ └┘ └┘
src           └───────────────┘
typ    └┘ └┘  └───────────────┘ └┘ └┘
640    (λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, ⟦⟨α ⊕ β, sum.lex r s, by exactI sum.lex.is_well_order⟩⟧
id                                 └─────┘                └───────────────────┘ 
src                                      └─────┘         └─────┘└───────────────────┘ 
typ                                └─────┘         └─────┘└───────────────────┘ 
doc                                        └─────┘         └─────┘
txt                                                        └─────┘
par                                                        └─────┘
pid                                                              
st                                                        └───────────────────────────┘
641      : Well_order → Well_order → ordinal) $
id         └────────┘   └────────┘   └─────┘
src        └────────┘   └────────┘   └─────┘
typ        └────────┘   └────────┘   └─────┘
doc                                  └─────┘
642  λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
id                                                       
typ                                                      
643  quot.sound ⟨order_iso.sum_lex_congr f g⟩⟩
id   └────────┘  └─────────────────────┘
src  └────────┘  └─────────────────────┘
typ  └────────┘  └─────────────────────┘
644  
645  @[simp] theorem type_add {α β : Type u} (r : α → α → Prop) (s : β → β → Prop)
id                                                                    
typ                                                                   
doc    └──┘
646    [is_well_order α r] [is_well_order β s] : type r + type s = type (sum.lex r s) := rfl
id      └───────────┘     └───────────┘      └──┘   └──┘   └──┘  └─────┘       └─┘
src     └───────────┘       └───────────┘        └──┘    └──┘    └──┘  └─────┘         └─┘
typ     └───────────┘     └───────────┘      └──┘   └──┘   └──┘  └─────┘       └─┘
doc     └───────────┘       └───────────┘        └──┘     └──┘     └──┘  └─────┘
647  
648  /-- The ordinal successor is the smallest ordinal larger than `o`.
649    It is defined as `o + 1`. -/
650  def succ (o : ordinal) : ordinal := o + 1
id                 └─────┘    └─────┘     
src                └─────┘    └─────┘      
typ                └─────┘    └─────┘     
doc                └─────┘    └─────┘
651  
652  theorem succ_eq_add_one (o) : succ o = o + 1 := rfl
id                                 └──┘          └─┘
src                                └──┘            └─┘
typ                                └──┘          └─┘
doc                                └──┘
653  
654  theorem lt_succ_self (o : ordinal.{u}) : o < succ o :=
id                             └─────┘          └──┘ 
src                            └─────┘           └──┘
typ                            └─────┘          └──┘ 
doc                            └─────┘            └──┘
655  induction_on o $ λ α r _, ⟨⟨⟨⟨λ x, sum.inl x, λ _ _, sum.inl.inj⟩,
id   └──────────┘                  └─────┘        └─────────┘
src  └──────────┘                       └─────┘           └─────────┘
typ  └──────────┘                  └─────┘        └─────────┘
656    λ _ _, sum.lex_inl_inl.symm⟩,
id          └─────────────┘└───┘
src           └─────────────┘└───┘
typ         └─────────────┘└───┘
657  sum.inr punit.star, λ b, sum.rec_on b
id   └─────┘ └────────┘      └────────┘ 
src  └─────┘ └────────┘       └────────┘
typ  └─────┘ └────────┘      └────────┘ 
658    (λ x, ⟨λ _, ⟨x, rfl⟩, λ _, sum.lex.sep _ _ _ _⟩)
id                  └─┘       └─────────┘
src                    └─┘        └─────────┘
typ                 └─┘       └─────────┘
659    (λ x, sum.lex_inr_inr.trans ⟨false.elim, λ ⟨x, H⟩, sum.inl_ne_inr H⟩)⟩⟩
id          └─────────────┘└────┘  └────────┘          └────────────┘
src          └─────────────┘└────┘  └────────┘            └────────────┘
typ         └─────────────┘└────┘  └────────┘          └────────────┘
660  
661  theorem succ_pos (o : ordinal) : 0 < succ o :=
id                         └─────┘       └──┘ 
src                        └─────┘       └──┘
typ                        └─────┘       └──┘ 
doc                        └─────┘        └──┘
662  lt_of_le_of_lt (zero_le _) (lt_succ_self _)
id   └────────────┘  └─────┘     └──────────┘
src  └────────────┘  └─────┘     └──────────┘
typ  └────────────┘  └─────┘     └──────────┘
663  
664  theorem succ_ne_zero (o : ordinal) : succ o ≠ 0 :=
id                             └─────┘    └──┘  
src                            └─────┘    └──┘   
typ                            └─────┘    └──┘  
doc                            └─────┘    └──┘
665  ne_of_gt $ succ_pos o
id   └──────┘   └──────┘ 
src  └──────┘   └──────┘
typ  └──────┘   └──────┘ 
666  
667  theorem succ_le {a b : ordinal} : succ a ≤ b ↔ a < b :=
id                          └─────┘    └──┘       
src                         └─────┘    └──┘         
typ                         └─────┘    └──┘       
doc                         └─────┘    └──┘
668  ⟨lt_of_lt_of_le (lt_succ_self _),
id    └────────────┘  └──────────┘
src   └────────────┘  └──────────┘
typ   └────────────┘  └──────────┘
669  induction_on a $ λ α r hr, induction_on b $ λ β s hs ⟨⟨f, t, hf⟩⟩, begin
id   └──────────┘        └┘  └──────────┘        └┘ 
src  └──────────┘               └──────────┘
typ  └──────────┘        └┘  └──────────┘        └┘ 
st                                                                      └─────
670    refine ⟨⟨@order_embedding.of_monotone (α ⊕ punit) β _ _
id               └─────────────────────────┘    └───┘  
src    └─────┘   └─────────────────────────┘  └───┘└┘ └────
typ    └─────┘   └─────────────────────────┘ └───┘└┘└────
doc    └─────┘   └─────────────────────────┘        └┘ └────
txt    └─────┘                                      └┘ └────
par    └─────┘                                      └┘ └────
pid                                                └┘ └────
st   ──────────────────────────────────────────────────────────
671      (@sum.lex.is_well_order _ _ _ _ hr _).1.1
id         └───────────────────┘         └┘
src  ───┘  └───────────────────┘└───────┘  └───────
typ  ───┘  └───────────────────┘└───────┘└┘└───────
doc  ───┘                       └───────┘  └───────
txt  ───┘                       └───────┘  └───────
par  ───┘                       └───────┘  └───────
pid  ───┘                       └───────┘  └───────
st   ──────────────────────────────────────────────
672      (@is_asymm_of_is_trans_of_is_irrefl _ _ hs.1.2.2 hs.1.2.1)
id         └───────────────────────────────┘              └┘
src  ───┘  └───────────────────────────────┘└───┘  └─────┘  └───────
typ  ───┘  └───────────────────────────────┘└───┘  └─────┘└┘└───────
doc  ───┘                                   └───┘  └─────┘  └───────
txt  ───┘                                   └───┘  └─────┘  └───────
par  ───┘                                   └───┘  └─────┘  └───────
pid  ───┘                                   └───┘  └─────┘  └───────
st   ───────────────────────────────────────────────────────────────
673      (sum.rec _ _) (λ a b, _), λ a b, _⟩⟩,
id        └─────┘
src  ───┘ └─────┘└────┘  └────────┘ └───────┘
typ  ───┘ └─────┘└────┘  └────────┘ └───────┘
doc  ───┘        └────┘  └────────┘ └───────┘
txt  ───┘        └────┘  └────────┘ └───────┘
par  ───┘        └────┘  └────────┘ └───────┘
pid  ───┘        └────┘  └────────┘ └───────┘
st   ───────────────────────────────────────┘└─
674    { exact f }, { exact λ _, t },
id                              
src      └────┘      └────┘ └──┘ 
typ      └────┘     └────┘ └──┘
doc      └────┘      └────┘ └──┘ 
txt      └────┘      └────┘ └──┘ 
par      └────┘      └────┘ └──┘ 
pid                       └──┘ 
st   ───┘└──────┘└┘└─┘└───────────┘└┘
675    { rcases a with a|_; rcases b with b|_,
id                                
src      └─────┘ └───────┘  └─────┘ └───────┘
typ      └─────┘└───────┘  └─────┘└───────┘
doc      └─────┘ └───────┘  └─────┘ └───────┘
txt      └─────┘ └───────┘  └─────┘ └───────┘
par      └─────┘ └───────┘  └─────┘ └───────┘
pid             └───────┘         └───────┘
st   ───┘└──────────────────────────────────┘└─
676      { simpa only [sum.lex_inl_inl] using f.ord'.1 },
id                     └─────────────┘        └────┘
src        └──────────┘└─────────────┘└──────┘└────┘└─┘
typ        └──────────┘└─────────────┘└──────┘└────┘└─┘
doc        └──────────┘               └──────┘      └─┘
txt        └──────────┘               └──────┘      └─┘
par        └──────────┘               └──────┘      └─┘
pid             └──┘└┘               └────┘      └─┘
st   ─────┘└──────────────────────────────────────────┘└┘
677      { intro _, rw hf, exact ⟨_, rfl⟩ },
id                     └┘            └─┘
src        └─────┘  └─┘    └────┘ └─┘└─┘└┘
typ        └─────┘  └─┘└┘  └────┘ └─┘└─┘└┘
doc        └─────┘  └─┘    └────┘ └─┘   └┘
txt        └─────┘  └─┘    └────┘ └─┘   └┘
par        └─────┘  └─┘    └────┘ └─┘   └┘
pid             └┘              └─┘   
st   ─────┘└─────┘└─────┘└───────────────┘└┘
678      { exact false.elim ∘ sum.lex_inr_inl },
id               └────────┘  └─────────────┘
src        └────┘└────────┘└─────────────┘
typ        └────┘└────────┘└─────────────┘
doc        └────┘                          
txt        └────┘                          
par        └────┘                          
pid                                       
st   ─────┘└─────────────────────────────────┘└┘
679      { exact false.elim ∘ sum.lex_inr_inr.1 } },
id               └────────┘   └─────────────┘
src        └────┘└────────┘ └─────────────┘└─┘
typ        └────┘└────────┘ └─────────────┘└─┘
doc        └────┘                          └─┘
txt        └────┘                          └─┘
par        └────┘                          └─┘
pid                                       └─┘
st   ──────────────────────────────────────────┘└──┘
680    { rcases a with a|_,
id              
src      └─────┘ └───────┘
typ      └─────┘└───────┘
doc      └─────┘ └───────┘
txt      └─────┘ └───────┘
par      └─────┘ └───────┘
pid             └───────┘
st   ────────────────────┘└─
681      { intro h, have := @principal_seg.init _ _ _ _ hs.1.2.2 ⟨f, t, hf⟩ _ _ h,
id                           └────────────────┘         └┘            └┘      
src        └─────┘  └──────┘ └────────────────┘└───────┘  └─────┘  └┘ └┘  └────┘
typ        └─────┘  └──────┘ └────────────────┘└───────┘└┘└─────┘ └┘└┘└┘└────┘
doc        └─────┘  └──────┘                   └───────┘  └─────┘  └┘ └┘  └────┘
txt        └─────┘  └──────┘                   └───────┘  └─────┘  └┘ └┘  └────┘
par        └─────┘  └──────┘                   └───────┘  └─────┘  └┘ └┘  └────┘
pid             └┘  └───┘└─┘                   └───────┘  └─────┘  └┘ └┘  └────┘
st   ─────┘└─────┘└─────────────────────────────────────────────────────────────┘└─
682        cases this with w h, exact ⟨sum.inl w, h⟩ },
id               └──┘                  └─────┘   
src        └────┘    └───────┘  └────┘ └─────┘ └┘ └┘
typ        └────┘└──┘└───────┘  └────┘ └─────┘└┘└┘
doc        └────┘    └───────┘  └────┘         └┘ └┘
txt        └────┘    └───────┘  └────┘         └┘ └┘
par        └────┘    └───────┘  └────┘         └┘ └┘
pid                 └───────┘                └┘ 
st   ────────────────────────┘└─────────────────────┘└┘
683      { intro h, cases (hf b).1 h with w h, exact ⟨sum.inl w, h⟩ } }
id                         └┘                       └─────┘   
src        └─────┘  └────┘    └──┘ └───────┘  └────┘ └─────┘ └┘ └┘
typ        └─────┘  └────┘ └┘└──┘└───────┘  └────┘ └─────┘└┘└┘
doc        └─────┘  └────┘    └──┘ └───────┘  └────┘         └┘ └┘
txt        └─────┘  └────┘    └──┘ └───────┘  └────┘         └┘ └┘
par        └─────┘  └────┘    └──┘ └───────┘  └────┘         └┘ └┘
pid             └┘           └──┘ └───────┘                └┘ 
st   ────────────┘└─────────────────────────┘└─────────────────────┘└───
684  end⟩
st   ──┘
685  
686  @[simp] theorem card_add (o₁ o₂ : ordinal) : card (o₁ + o₂) = card o₁ + card o₂ :=
id                                     └─────┘    └──┘  └┘  └┘   └──┘ └┘  └──┘ └┘
src                                    └─────┘    └──┘           └──┘     └──┘
typ                                    └─────┘    └──┘  └┘  └┘   └──┘ └┘  └──┘ └┘
doc    └──┘                            └─────┘    └──┘             └──┘      └──┘
687  induction_on o₁ $ λ α r _, induction_on o₂ $ λ β s _, rfl
id   └──────────┘ └┘         └──────────┘ └┘         └─┘
src  └──────────┘               └──────────┘               └─┘
typ  └──────────┘ └┘         └──────────┘ └┘         └─┘
688  
689  @[simp] theorem card_succ (o : ordinal) : card (succ o) = card o + 1 :=
id                                  └─────┘    └──┘  └──┘    └──┘  
src                                 └─────┘    └──┘  └──┘     └──┘   
typ                                 └─────┘    └──┘  └──┘    └──┘  
doc    └──┘                         └─────┘    └──┘  └──┘      └──┘
690  by simp only [succ, card_add, card_one]
id                 └──┘  └──────┘  └──────┘
src     └─────────┘└──┘└┘└──────┘└┘└──────┘└─
typ     └─────────┘└──┘└┘└──────┘└┘└──────┘└─
doc     └─────────┘└──┘└┘        └┘        └─
txt     └─────────┘    └┘        └┘        └─
par     └─────────┘    └┘        └┘        └─
pid         └──┘└┘    └┘        └┘        
st     └─────────────────────────────────────
691  
src  
typ  
doc  
txt  
par  
pid  
st   
692  @[simp] theorem card_nat (n : ℕ) : card.{u} n = n :=
id                                     └──┘       
src                                    └──┘       
typ                                    └──┘       
doc    └──┘                             └──┘
693  by induction n; [refl, simp only [card_add, card_one, nat.cast_succ, *]]
id                                   └──────┘  └──────┘  └───────────┘
src     └────────┘   └──┘  └─────────┘└──────┘└┘└──────┘└┘└───────────┘└──┘
typ     └────────┘  └──┘  └─────────┘└──────┘└┘└──────┘└┘└───────────┘└──┘
doc     └────────┘    └──┘  └─────────┘        └┘        └┘             └──┘
txt     └────────┘    └──┘  └─────────┘        └┘        └┘             └──┘
par     └────────┘    └──┘  └─────────┘        └┘        └┘             └──┘
pid                            └──┘└┘        └┘        └┘             └──┘
st     └────────────────────────────────────────────────────────────────────┘
694  
695  theorem nat_cast_succ (n : ℕ) : (succ n : ordinal) = n.succ := rfl
id                                   └──┘    └─────┘   └───┘    └─┘
src                                  └──┘     └─────┘    └───┘    └─┘
typ                                  └──┘    └─────┘   └───┘    └─┘
doc                                   └──┘     └─────┘
696  
697  instance : add_monoid ordinal.{u} :=
id              └────────┘ └─────┘
src             └────────┘ └─────┘
typ             └────────┘ └─────┘
doc                        └─────┘
698  { add       := (+),
id                  
src                 
typ                 
699    zero      := 0,
700    zero_add  := λ o, induction_on o $ λ α r _, eq.symm $ quotient.sound
id                      └──────────┘          └─────┘   └────────────┘
src                      └──────────┘              └─────┘   └────────────┘
typ                     └──────────┘          └─────┘   └────────────┘
701      ⟨⟨(pempty_sum α).symm, λ a b, sum.lex_inr_inr.symm⟩⟩,
id          └────────┘  └──┘        └─────────────┘└───┘
src         └────────┘   └──┘          └─────────────┘└───┘
typ         └────────┘  └──┘        └─────────────┘└───┘
702    add_zero  := λ o, induction_on o $ λ α r _, eq.symm $ quotient.sound
id                      └──────────┘          └─────┘   └────────────┘
src                      └──────────┘              └─────┘   └────────────┘
typ                     └──────────┘          └─────┘   └────────────┘
703      ⟨⟨(sum_pempty α).symm, λ a b, sum.lex_inl_inl.symm⟩⟩,
id          └────────┘  └──┘        └─────────────┘└───┘
src         └────────┘   └──┘          └─────────────┘└───┘
typ         └────────┘  └──┘        └─────────────┘└───┘
704    add_assoc := λ o₁ o₂ o₃, quotient.induction_on₃ o₁ o₂ o₃ $
id                    └┘ └┘ └┘  └────────────────────┘ └┘ └┘ └┘
src                             └────────────────────┘
typ                   └┘ └┘ └┘  └────────────────────┘ └┘ └┘ └┘
705      λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩, quot.sound
id                                     └────────┘
src                                       └────────┘
typ                                    └────────┘
706      ⟨⟨sum_assoc _ _ _, λ a b,
id         └───────┘           
src        └───────┘
typ        └───────┘           
707      begin rcases a with ⟨a|a⟩|a; rcases b with ⟨b|b⟩|b;
id                                          
src            └─────┘ └───────────┘  └─────┘ └───────────┘
typ            └─────┘└───────────┘  └─────┘└───────────┘
doc            └─────┘ └───────────┘  └─────┘ └───────────┘
txt            └─────┘ └───────────┘  └─────┘ └───────────┘
par            └─────┘ └───────────┘  └─────┘ └───────────┘
pid                   └───────────┘         └───────────┘
st       └───────────────────────────────────────────────────
708        simp only [sum_assoc_apply_in1, sum_assoc_apply_in2, sum_assoc_apply_in3,
id                    └─────────────────┘  └─────────────────┘  └─────────────────┘
src        └─────────┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
typ        └─────────┘└─────────────────┘└┘└─────────────────┘└┘└─────────────────┘└─
doc        └─────────┘                   └┘                   └┘                   └─
txt        └─────────┘                   └┘                   └┘                   └─
par        └─────────┘                   └┘                   └┘                   └─
pid            └──┘└┘                   └┘                   └┘                   └─
st   ────────────────────────────────────────────────────────────────────────────────
709          sum.lex_inl_inl, sum.lex_inr_inr, sum.lex.sep, sum.lex_inr_inl] end⟩⟩ }
id           └─────────────┘  └─────────────┘  └─────────┘  └─────────────┘
src  ───────┘└─────────────┘└┘└─────────────┘└┘└─────────┘└┘└─────────────┘└┘
typ  ───────┘└─────────────┘└┘└─────────────┘└┘└─────────┘└┘└─────────────┘└┘
doc  ───────┘               └┘               └┘           └┘               └┘
txt  ───────┘               └┘               └┘           └┘               └┘
par  ───────┘               └┘               └┘           └┘               └┘
pid  ───────┘               └┘               └┘           └┘               
st   ───────────────────────────────────────────────────────────────────────┘└─┘
710  
711  theorem add_succ (o₁ o₂ : ordinal) : o₁ + succ o₂ = succ (o₁ + o₂) :=
id                             └─────┘    └┘  └──┘ └┘  └──┘  └┘  └┘
src                            └─────┘        └──┘     └──┘     
typ                            └─────┘    └┘  └──┘ └┘  └──┘  └┘  └┘
doc                            └─────┘         └──┘      └──┘
712  (add_assoc _ _ _).symm
id    └───────┘       └──┘
src   └───────┘       └──┘
typ   └───────┘       └──┘
713  
714  @[simp] theorem succ_zero : succ 0 = 1 := zero_add _
id                               └──┘         └──────┘
src                              └──┘         └──────┘
typ                              └──┘         └──────┘
doc    └──┘                      └──┘
715  
716  theorem one_le_iff_pos {o : ordinal} : 1 ≤ o ↔ 0 < o :=
id                               └─────┘            
src                              └─────┘            
typ                              └─────┘            
doc                              └─────┘
717  by rw [← succ_zero, succ_le]
id            └───────┘  └─────┘
src     └────┘└───────┘└┘└─────┘└─
typ     └────┘└───────┘└┘└─────┘└─
doc     └────┘         └┘       └─
txt     └────┘         └┘       └─
par     └────┘         └┘       └─
pid       └──┘         └┘       
st     └──────────────┘└───────┘
718  
src  
typ  
doc  
txt  
par  
pid  
st   
719  theorem one_le_iff_ne_zero {o : ordinal} : 1 ≤ o ↔ o ≠ 0 :=
id                                   └─────┘          
src                                  └─────┘            
typ                                  └─────┘          
doc                                  └─────┘
720  by rw [one_le_iff_pos, pos_iff_ne_zero]
id          └────────────┘  └─────────────┘
src     └──┘└────────────┘└┘└─────────────┘└─
typ     └──┘└────────────┘└┘└─────────────┘└─
doc     └──┘              └┘               └─
txt     └──┘              └┘               └─
par     └──┘              └┘               └─
pid       └┘              └┘               
st     └─────────────────┘└───────────────┘
721  
src  
typ  
doc  
txt  
par  
pid  
st   
722  theorem add_le_add_left {a b : ordinal} : a ≤ b → ∀ c, c + a ≤ c + b :=
id                                  └─────┘                   
src                                 └─────┘                        
typ                                 └─────┘                   
doc                                 └─────┘
723  induction_on a $ λ α₁ r₁ _, induction_on b $ λ α₂ r₂ _ ⟨⟨⟨f, fo⟩, fi⟩⟩ c,
id   └──────────┘      └┘ └┘   └──────────┘      └┘ └┘      └┘   └┘   
src  └──────────┘                └──────────┘
typ  └──────────┘      └┘ └┘   └──────────┘      └┘ └┘      └┘   └┘   
724  induction_on c $ λ β s _,
id   └──────────┘        
src  └──────────┘
typ  └──────────┘        
725  ⟨⟨⟨(embedding.refl _).sum_congr f,
id       └────────────┘   └───────┘
src      └────────────┘   └───────┘
typ      └────────────┘   └───────┘
726    λ a b, match a, b with
id                  
typ                 
727      | sum.inl a, sum.inl b := sum.lex_inl_inl.trans sum.lex_inl_inl.symm
id                    └─────┘      └─────────────┘└────┘ └─────────────┘└───┘
src                   └─────┘      └─────────────┘└────┘ └─────────────┘└───┘
typ                   └─────┘      └─────────────┘└────┘ └─────────────┘└───┘
728      | sum.inl a, sum.inr b := by apply iff_of_true; apply sum.lex.sep
id         └─────┘    └─────┘               └─────────┘        └─────────┘
src        └─────┘    └─────┘         └────┘└─────────┘  └────┘└─────────┘
typ        └─────┘    └─────┘         └────┘└─────────┘  └────┘└─────────┘
doc                                   └────┘             └────┘           
txt                                   └────┘             └────┘           
par                                   └────┘             └────┘           
pid                                                                     
st                                   └─────────────────────────────────────
729      | sum.inr a, sum.inl b := by apply iff_of_false; exact sum.lex_inr_inl
id         └─────┘    └─────┘               └──────────┘        └─────────────┘
src  ───┘  └─────┘    └─────┘         └────┘└──────────┘  └────┘└─────────────┘
typ  ───┘  └─────┘    └─────┘         └────┘└──────────┘  └────┘└─────────────┘
doc  ───┘                             └────┘              └────┘               
txt  ───┘                             └────┘              └────┘               
par  ───┘                             └────┘              └────┘               
pid  ───┘                                                                    
st   ───┘                            └──────────────────────────────────────────
730      | sum.inr a, sum.inr b := sum.lex_inr_inr.trans $ fo.trans sum.lex_inr_inr.symm
id                    └─────┘      └─────────────┘└────┘     └────┘ └─────────────┘└───┘
src  ───┘             └─────┘      └─────────────┘└────┘     └────┘ └─────────────┘└───┘
typ  ───┘             └─────┘      └─────────────┘└────┘     └────┘ └─────────────┘└───┘
doc  ───┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘
731      end⟩,
732    λ a b H, match a, b, H with
id                     
typ                    
733      | _,         sum.inl b, _ := ⟨sum.inl b, rfl⟩
id                    └─────┘         └─────┘    └─┘
src                   └─────┘          └─────┘    └─┘
typ                   └─────┘         └─────┘    └─┘
734      | sum.inl a, sum.inr b, H := (sum.lex_inr_inl H).elim
id         └─────┘    └─────┘         └─────────────┘   └──┘
src        └─────┘    └─────┘          └─────────────┘   └──┘
typ        └─────┘    └─────┘         └─────────────┘   └──┘
735      | sum.inr a, sum.inr b, H := let ⟨w, h⟩ := fi _ _ (sum.lex_inr_inr.1 H) in
id                    └─────┘        └─┘                 └─────────────┘
src                   └─────┘                               └─────────────┘
typ                   └─────┘        └─┘                 └─────────────┘
736          ⟨sum.inr w, congr_arg sum.inr h⟩
id            └─────┘    └───────┘ └─────┘
src           └─────┘    └───────┘ └─────┘
typ           └─────┘    └───────┘ └─────┘
737    end⟩⟩
738  
739  theorem le_add_right (a b : ordinal) : a ≤ a + b :=
id                               └─────┘        
src                              └─────┘         
typ                              └─────┘        
doc                              └─────┘
740  by simpa only [add_zero] using add_le_add_left (zero_le b) a
id                  └──────┘        └─────────────┘  └─────┘   
src     └──────────┘└──────┘└──────┘└─────────────┘ └─────┘ └┘ 
typ     └──────────┘└──────┘└──────┘└─────────────┘ └─────┘└┘
doc     └──────────┘        └──────┘                        └┘ 
txt     └──────────┘        └──────┘                        └┘ 
par     └──────────┘        └──────┘                        └┘ 
pid          └──┘└┘        └────┘                        └┘ 
st     └──────────────────────────────────────────────────────────
741  
src  
typ  
doc  
txt  
par  
pid  
st   
742  theorem add_le_add_iff_left (a) {b c : ordinal} : a + b ≤ a + c ↔ b ≤ c :=
id                                          └─────┘              
src                                         └─────┘                  
typ                                         └─────┘              
doc                                         └─────┘
743  ⟨induction_on a $ λ α r hr, induction_on b $ λ β₁ s₁ hs₁, induction_on c $ λ β₂ s₂ hs₂ ⟨f⟩, ⟨
id    └──────────┘        └┘  └──────────┘      └┘ └┘ └─┘  └──────────┘      └┘ └┘ └─┘ 
src   └──────────┘               └──────────┘                  └──────────┘
typ   └──────────┘        └┘  └──────────┘      └┘ └┘ └─┘  └──────────┘      └┘ └┘ └─┘ 
744    have fl : ∀ a, f (sum.inl a) = sum.inl a := λ a,
id                      └─────┘    └─────┘       
src                      └─────┘     └─────┘
typ                     └─────┘    └─────┘       
745      by simpa only [initial_seg.trans_apply, initial_seg.le_add_apply]
id                      └─────────────────────┘  └──────────────────────┘
src         └──────────┘└─────────────────────┘└┘└──────────────────────┘└─
typ         └──────────┘└─────────────────────┘└┘└──────────────────────┘└─
doc         └──────────┘                       └┘                        └─
txt         └──────────┘                       └┘                        └─
par         └──────────┘                       └┘                        └─
pid              └──┘└┘                       └┘                        
st         └───────────────────────────────────────────────────────────────
746        using @initial_seg.eq _ _ _ _ (@sum.lex.is_well_order _ _ _ _ hr hs₂)
id                └────────────┘           └───────────────────┘         └┘ └─┘
src  ───────────┘ └────────────┘└───────┘  └───────────────────┘└───────┘     └─
typ  ───────────┘ └────────────┘└───────┘  └───────────────────┘└───────┘└┘└─┘└─
doc  ───────────┘               └───────┘                       └───────┘     └─
txt  ───────────┘               └───────┘                       └───────┘     └─
par  ───────────┘               └───────┘                       └───────┘     └─
pid  ─────┘└────┘               └───────┘                       └───────┘     └─
st   ────────────────────────────────────────────────────────────────────────────
747          ((initial_seg.le_add r s₁).trans f) (initial_seg.le_add r s₂) a,
id                                  └┘           └────────────────┘  └┘  
src  ───────┘                       └──────┘ └┘ └────────────────┘   └┘
typ  ───────┘                     └┘└──────┘└┘ └────────────────┘└┘└┘
doc  ───────┘                       └──────┘ └┘                      └┘
txt  ───────┘                       └──────┘ └┘                      └┘
par  ───────┘                       └──────┘ └┘                      └┘
pid  ───────┘                       └──────┘ └┘                      └┘
st   ──────────────────────────────────────────────────────────────────────┘
748    have ∀ b, {b' // f (sum.inr b) = sum.inr b'}, begin
id              └┘       └─────┘    └─────┘ └┘
src                       └─────┘     └─────┘
typ             └┘       └─────┘    └─────┘ └┘
st                                                   └─────
749      intro b, cases e : f (sum.inr b),
id                            └─────┘ 
src      └─────┘  └────┘ └─┘  └─────┘ 
typ      └─────┘  └────┘ └─┘ └─────┘
doc      └─────┘  └────┘ └─┘          
txt      └─────┘  └────┘ └─┘          
par      └─────┘  └────┘ └─┘          
pid           └┘        └─┘          
st   ──────────┘└───────────────────────┘└─
750      { rw ← fl at e, have := f.inj e, contradiction },
id              └┘               └───┘ 
src        └───┘  └───┘  └──────┘└───┘   └────────────┘
typ        └───┘└┘└───┘  └──────┘└───┘  └────────────┘
doc        └───┘  └───┘  └──────┘        └────────────┘
txt        └───┘  └───┘  └──────┘        └────────────┘
par        └───┘  └───┘  └──────┘        └────────────┘
pid          └─┘  └───┘  └───┘└─┘                     
st   ─────┘└──────────┘└───────────────┘└──────────────┘└┘
751      { exact ⟨_, rfl⟩ }
id                   └─┘
src        └────┘ └─┘└─┘└┘
typ        └────┘ └─┘└─┘└┘
doc        └────┘ └─┘   └┘
txt        └────┘ └─┘   └┘
par        └────┘ └─┘   └┘
pid              └─┘   
st   ────────────────────┘└─
752    end,
st   ────┘
753    let g (b) := (this b).1 in
id                 └──┘  
src                         
typ                └──┘  
754    have fr : ∀ b, f (sum.inr b) = sum.inr (g b), from λ b, (this b).2,
id                      └─────┘    └─────┘                └──┘  
src                      └─────┘     └─────┘                          
typ                     └─────┘    └─────┘                └──┘  
755    ⟨⟨⟨g, λ x y h, by injection f.inj
id                             └───┘
src                      └────────┘└───┘
typ                  └────────┘└───┘
doc                      └────────┘     
txt                      └────────┘     
par                      └────────┘     
pid                                    
st                      └────────────────
756      (by rw [fr, fr, h] : f (sum.inr x) = f (sum.inr y))⟩,
id               └┘  └┘                       └─────┘ 
src  ───┘   └──┘  └┘  └┘ └┘└┘          └┘   └─────┘ └┘
typ  ───┘   └──┘└┘└┘└┘└┘└┘└┘         └┘  └─────┘└┘
doc  ───┘   └──┘  └┘  └┘ └┘└┘          └┘           └┘
txt  ───┘   └──┘  └┘  └┘ └┘└┘          └┘           └┘
par  ───┘   └──┘  └┘  └┘ └┘└┘          └┘           └┘
pid  ───┘   └───┘  └┘  └┘ └──┘          └┘           └┘
st   ──────┘└─────┘└──┘└─┘└──────────────────────────────┘
757      λ a b, by simpa only [sum.lex_inr_inr, fr, order_embedding.coe_fn_to_embedding,
id                           └─────────────┘  └┘  └─────────────────────────────────┘
src                └──────────┘└─────────────┘└┘  └┘└─────────────────────────────────┘└─
typ              └──────────┘└─────────────┘└┘└┘└┘└─────────────────────────────────┘└─
doc                └──────────┘               └┘  └┘                                   └─
txt                └──────────┘               └┘  └┘                                   └─
par                └──────────┘               └┘  └┘                                   └─
pid                     └──┘└┘               └┘  └┘                                   └─
st                └──────────────────────────────────────────────────────────────────────
758          initial_seg.coe_fn_to_order_embedding, function.embedding.coe_fn_mk]
id           └───────────────────────────────────┘  └──────────────────────────┘
src  ───────┘└───────────────────────────────────┘└┘└──────────────────────────┘└─
typ  ───────┘└───────────────────────────────────┘└┘└──────────────────────────┘└─
doc  ───────┘                                     └┘                            └─
txt  ───────┘                                     └┘                            └─
par  ───────┘                                     └┘                            └─
pid  ───────┘                                     └┘                            
st   ─────────────────────────────────────────────────────────────────────────────
759        using @order_embedding.ord _ _ _ _ f.to_order_embedding (sum.inr a) (sum.inr b)⟩,
id                └─────────────────┘         └──────────────────┘             └─────┘ 
src  ───────────┘ └─────────────────┘└───────┘└──────────────────┘         └┘ └─────┘ 
typ  ───────────┘ └─────────────────┘└───────┘└──────────────────┘        └┘ └─────┘
doc  ───────────┘                    └───────┘                             └┘         
txt  ───────────┘                    └───────┘                             └┘         
par  ───────────┘                    └───────┘                             └┘         
pid  ─────┘└────┘                    └───────┘                             └┘         
st   ────────────────────────────────────────────────────────────────────────────────────┘
760      λ a b H, begin
id           
typ          
st                └─────
761        rcases f.init' (by rw fr; exact sum.lex_inr_inr.2 H) with ⟨a'|a', h⟩,
id                └─────┘        └┘        └─────────────┘   
src        └─────┘└─────┘   └─┘  └┘└────┘└─────────────┘└─┘ └───────────────┘
typ        └─────┘└─────┘   └─┘└┘└┘└────┘└─────────────┘└─┘└───────────────┘
doc        └─────┘          └─┘  └┘└────┘               └─┘ └───────────────┘
txt        └─────┘          └─┘  └┘└────┘               └─┘ └───────────────┘
par        └─────┘          └─┘  └┘└────┘               └─┘ └───────────────┘
pid                        └──┘  └──────┘               └─┘ └───────────────┘
st   ───────────────────────┘└───────────────────────────────┘└───────────────┘└─
762        { rw fl at h, cases h },
id              └┘
src          └─┘  └───┘
typ          └─┘└┘└───┘
doc          └─┘  └───┘
txt          └─┘  └───┘
par          └─┘  └───┘
pid              └───┘
st   ───────┘└────────┘          
763        { rw fr at h, exact ⟨a', sum.inr.inj h⟩ }
st                                                 └─
764      end⟩⟩,
st   ──────┘
765  λ h, add_le_add_left h _⟩
id       └─────────────┘ 
src       └─────────────┘
typ      └─────────────┘ 
766  
767  theorem add_left_cancel (a) {b c : ordinal} : a + b = a + c ↔ b = c :=
id                                      └─────┘              
src                                     └─────┘                  
typ                                     └─────┘              
doc                                     └─────┘
768  by simp only [le_antisymm_iff, add_le_add_iff_left]
id                 └─────────────┘  └─────────────────┘
src     └─────────┘└─────────────┘└┘└─────────────────┘└─
typ     └─────────┘└─────────────┘└┘└─────────────────┘└─
doc     └─────────┘               └┘                   └─
txt     └─────────┘               └┘                   └─
par     └─────────┘               └┘                   └─
pid         └──┘└┘               └┘                   
st     └─────────────────────────────────────────────────
769  
src  
typ  
doc  
txt  
par  
pid  
st   
770  /-- The universe lift operation for ordinals, which embeds `ordinal.{u}` as
771    a proper initial segment of `ordinal.{v}` for `v > u`. -/
772  def lift (o : ordinal.{u}) : ordinal.{max u v} :=
id                 └─────┘        └─────┘
src                └─────┘        └─────┘
typ                └─────┘        └─────┘
doc                └─────┘        └─────┘
773  quotient.lift_on o (λ ⟨α, r, wo⟩,
id   └──────────────┘         └┘
src  └──────────────┘
typ  └──────────────┘         └┘
774    @type _ _ (@order_embedding.is_well_order _ _ (@equiv.ulift.{u v} α ⁻¹'o r) r
id      └──┘       └───────────────────────────┘       └─────────┘         └──┘
src     └──┘       └───────────────────────────┘       └─────────┘         └──┘
typ     └──┘       └───────────────────────────┘       └─────────┘         └──┘
doc     └──┘                                                               └──┘
775      (order_iso.preimage equiv.ulift.{u v} r) wo)) $
id        └────────────────┘ └─────────┘
src       └────────────────┘ └─────────┘
typ       └────────────────┘ └─────────┘
doc       └────────────────┘
776  λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨f⟩,
id                     
typ                    
777  quot.sound ⟨(order_iso.preimage equiv.ulift r).trans $
id   └────────┘   └────────────────┘ └─────────┘   └───┘
src  └────────┘   └────────────────┘ └─────────┘   └───┘
typ  └────────┘   └────────────────┘ └─────────┘   └───┘
doc               └────────────────┘
778    f.trans (order_iso.preimage equiv.ulift s).symm⟩
id      └────┘  └────────────────┘ └─────────┘   └──┘
src     └────┘  └────────────────┘ └─────────┘   └──┘
typ     └────┘  └────────────────┘ └─────────┘   └──┘
doc             └────────────────┘
779  
780  theorem lift_type {α} (r : α → α → Prop) [is_well_order α r] :
id                                           └───────────┘  
src                                            └───────────┘
typ                                          └───────────┘  
doc                                            └───────────┘
781    ∃ wo', lift (type r) = @type _ (@equiv.ulift.{u v} α ⁻¹'o r) wo' :=
id      └─┘ └──┘  └──┘     └──┘     └─────────┘        └──┘   └─┘
src         └──┘  └──┘      └──┘     └─────────┘         └──┘
typ     └─┘ └──┘  └──┘     └──┘     └─────────┘        └──┘   └─┘
doc           └──┘  └──┘       └──┘                         └──┘
782  ⟨_, rfl⟩
id       └─┘
src      └─┘
typ      └─┘
783  
784  theorem lift_umax : lift.{u (max u v)} = lift.{u v} :=
id                       └──┘                └──┘
src                      └──┘                └──┘
typ                      └──┘                └──┘
doc                      └──┘                 └──┘
785  funext $ λ a, induction_on a $ λ α r _,
id   └────┘       └──────────┘        
src  └────┘        └──────────┘
typ  └────┘       └──────────┘        
786  quotient.sound ⟨(order_iso.preimage equiv.ulift r).trans (order_iso.preimage equiv.ulift r).symm⟩
id   └────────────┘   └────────────────┘ └─────────┘  └───┘   └────────────────┘ └─────────┘  └──┘
src  └────────────┘   └────────────────┘ └─────────┘   └───┘   └────────────────┘ └─────────┘   └──┘
typ  └────────────┘   └────────────────┘ └─────────┘  └───┘   └────────────────┘ └─────────┘  └──┘
doc                   └────────────────┘                       └────────────────┘
787  
788  theorem lift_id' (a : ordinal) : lift a = a :=
id                         └─────┘    └──┘   
src                        └─────┘    └──┘   
typ                        └─────┘    └──┘   
doc                        └─────┘    └──┘
789  induction_on a $ λ α r _,
id   └──────────┘        
src  └──────────┘
typ  └──────────┘        
790  quotient.sound ⟨order_iso.preimage equiv.ulift r⟩
id   └────────────┘  └────────────────┘ └─────────┘ 
src  └────────────┘  └────────────────┘ └─────────┘
typ  └────────────┘  └────────────────┘ └─────────┘ 
doc                  └────────────────┘
791  
792  @[simp] theorem lift_id : ∀ a, lift.{u u} a = a := lift_id'.{u u}
id                                 └──┘             └──────┘
src                                 └──┘               └──────┘
typ                                └──┘             └──────┘
doc    └──┘                         └──┘
793  
794  @[simp] theorem lift_lift (a : ordinal) : lift.{(max u v) w} (lift.{u v} a) = lift.{u (max v w)} a :=
id                                  └─────┘    └──┘                └──┘          └──┘               
src                                 └─────┘    └──┘                └──┘           └──┘
typ                                 └─────┘    └──┘                └──┘          └──┘               
doc    └──┘                         └─────┘    └──┘                └──┘            └──┘
795  induction_on a $ λ α r _,
id   └──────────┘        
src  └──────────┘
typ  └──────────┘        
796  quotient.sound ⟨(order_iso.preimage equiv.ulift _).trans $
id   └────────────┘   └────────────────┘ └─────────┘   └───┘
src  └────────────┘   └────────────────┘ └─────────┘   └───┘
typ  └────────────┘   └────────────────┘ └─────────┘   └───┘
doc                   └────────────────┘
797    (order_iso.preimage equiv.ulift _).trans (order_iso.preimage equiv.ulift _).symm⟩
id      └────────────────┘ └─────────┘   └───┘   └────────────────┘ └─────────┘   └──┘
src     └────────────────┘ └─────────┘   └───┘   └────────────────┘ └─────────┘   └──┘
typ     └────────────────┘ └─────────┘   └───┘   └────────────────┘ └─────────┘   └──┘
doc     └────────────────┘                       └────────────────┘
798  
799  theorem lift_type_le {α : Type u} {β : Type v} {r s} [is_well_order α r] [is_well_order β s] :
id                                                         └───────────┘     └───────────┘  
src                                                        └───────────┘       └───────────┘
typ                                                        └───────────┘     └───────────┘  
doc                                                        └───────────┘       └───────────┘
800    lift.{u (max v w)} (type r) ≤ lift.{v (max u w)} (type s) ↔ nonempty (r ≼i s) :=
id     └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
src    └──┘                └──┘     └──┘                └──┘     └──────┘    └┘
typ    └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
doc    └──┘                └──┘      └──┘                └──┘                  └┘
801  ⟨λ ⟨f⟩, ⟨(initial_seg.of_iso (order_iso.preimage equiv.ulift r).symm).trans $
id           └────────────────┘  └────────────────┘ └─────────┘  └──┘  └───┘
src            └────────────────┘  └────────────────┘ └─────────┘   └──┘  └───┘
typ          └────────────────┘  └────────────────┘ └─────────┘  └──┘  └───┘
doc            └────────────────┘  └────────────────┘                     └───┘
802      f.trans (initial_seg.of_iso (order_iso.preimage equiv.ulift s))⟩,
id        └────┘  └────────────────┘  └────────────────┘ └─────────┘ 
src       └────┘  └────────────────┘  └────────────────┘ └─────────┘
typ       └────┘  └────────────────┘  └────────────────┘ └─────────┘ 
doc       └────┘  └────────────────┘  └────────────────┘
803   λ ⟨f⟩, ⟨(initial_seg.of_iso (order_iso.preimage equiv.ulift r)).trans $
id           └────────────────┘  └────────────────┘ └─────────┘   └───┘
src            └────────────────┘  └────────────────┘ └─────────┘    └───┘
typ          └────────────────┘  └────────────────┘ └─────────┘   └───┘
doc            └────────────────┘  └────────────────┘                └───┘
804      f.trans (initial_seg.of_iso (order_iso.preimage equiv.ulift s).symm)⟩⟩
id        └────┘  └────────────────┘  └────────────────┘ └─────────┘  └──┘
src       └────┘  └────────────────┘  └────────────────┘ └─────────┘   └──┘
typ       └────┘  └────────────────┘  └────────────────┘ └─────────┘  └──┘
doc       └────┘  └────────────────┘  └────────────────┘
805  
806  theorem lift_type_eq {α : Type u} {β : Type v} {r s} [is_well_order α r] [is_well_order β s] :
id                                                         └───────────┘     └───────────┘  
src                                                        └───────────┘       └───────────┘
typ                                                        └───────────┘     └───────────┘  
doc                                                        └───────────┘       └───────────┘
807    lift.{u (max v w)} (type r) = lift.{v (max u w)} (type s) ↔ nonempty (r ≃o s) :=
id     └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
src    └──┘                └──┘     └──┘                └──┘     └──────┘    └┘
typ    └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
doc    └──┘                └──┘      └──┘                └──┘                  └┘
808  quotient.eq.trans
id   └─────────┘└────┘
src  └─────────┘└────┘
typ  └─────────┘└────┘
809  ⟨λ ⟨f⟩, ⟨(order_iso.preimage equiv.ulift r).symm.trans $
id           └────────────────┘ └─────────┘  └──┘ └───┘
src            └────────────────┘ └─────────┘   └──┘ └───┘
typ          └────────────────┘ └─────────┘  └──┘ └───┘
doc            └────────────────┘
810      f.trans (order_iso.preimage equiv.ulift s)⟩,
id        └────┘  └────────────────┘ └─────────┘ 
src       └────┘  └────────────────┘ └─────────┘
typ       └────┘  └────────────────┘ └─────────┘ 
doc               └────────────────┘
811   λ ⟨f⟩, ⟨(order_iso.preimage equiv.ulift r).trans $
id           └────────────────┘ └─────────┘  └───┘
src            └────────────────┘ └─────────┘   └───┘
typ          └────────────────┘ └─────────┘  └───┘
doc            └────────────────┘
812      f.trans (order_iso.preimage equiv.ulift s).symm⟩⟩
id        └────┘  └────────────────┘ └─────────┘  └──┘
src       └────┘  └────────────────┘ └─────────┘   └──┘
typ       └────┘  └────────────────┘ └─────────┘  └──┘
doc               └────────────────┘
813  
814  theorem lift_type_lt {α : Type u} {β : Type v} {r s} [is_well_order α r] [is_well_order β s] :
id                                                         └───────────┘     └───────────┘  
src                                                        └───────────┘       └───────────┘
typ                                                        └───────────┘     └───────────┘  
doc                                                        └───────────┘       └───────────┘
815    lift.{u (max v w)} (type r) < lift.{v (max u w)} (type s) ↔ nonempty (r ≺i s) :=
id     └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
src    └──┘                └──┘     └──┘                └──┘     └──────┘    └┘
typ    └──┘                └──┘    └──┘                └──┘    └──────┘   └┘ 
doc    └──┘                └──┘      └──┘                └──┘
816  by haveI := @order_embedding.is_well_order _ _ (@equiv.ulift.{u (max v w)} α ⁻¹'o r)
id                └───────────────────────────┘       └─────────┘                └──┘
src     └───────┘ └───────────────────────────┘└───┘  └─────────┘└─────────────┘ └──┘ └─
typ     └───────┘ └───────────────────────────┘└───┘  └─────────┘└─────────────┘└──┘ └─
doc     └───────┘                              └───┘             └─────────────┘ └──┘ └─
txt     └───────┘                              └───┘             └─────────────┘      └─
par     └───────┘                              └───┘             └─────────────┘      └─
pid          └─┘                              └───┘             └─────────────┘      └─
st     └──────────────────────────────────────────────────────────────────────────────────
817       r (order_iso.preimage equiv.ulift.{u (max v w)} r) _;
id           └────────────────┘ └─────────┘               
src  ────┘  └────────────────┘└─────────┘└─────────────┘ └─┘
typ  ────┘  └────────────────┘└─────────┘└─────────────┘└─┘
doc  ────┘  └────────────────┘           └─────────────┘ └─┘
txt  ────┘                               └─────────────┘ └─┘
par  ────┘                               └─────────────┘ └─┘
pid  ────┘                               └─────────────┘ └─┘
st   ───────────────────────────────────────────────────────────
818     haveI := @order_embedding.is_well_order _ _ (@equiv.ulift.{v (max u w)} β ⁻¹'o s)
id                └───────────────────────────┘       └─────────┘               
src     └───────┘ └───────────────────────────┘└───┘  └─────────┘└─────────────┘      └─
typ     └───────┘ └───────────────────────────┘└───┘  └─────────┘└─────────────┘     └─
doc     └───────┘                              └───┘             └─────────────┘      └─
txt     └───────┘                              └───┘             └─────────────┘      └─
par     └───────┘                              └───┘             └─────────────┘      └─
pid          └─┘                              └───┘             └─────────────┘      └─
st   ─────────────────────────────────────────────────────────────────────────────────────
819       s (order_iso.preimage equiv.ulift.{v (max u w)} s) _; exact
id           └────────────────┘ └─────────┘               
src  ────┘  └────────────────┘└─────────┘└─────────────┘ └─┘  └────┘
typ  ────┘  └────────────────┘└─────────┘└─────────────┘└─┘  └────┘
doc  ────┘  └────────────────┘           └─────────────┘ └─┘  └────┘
txt  ────┘                               └─────────────┘ └─┘  └────┘
par  ────┘                               └─────────────┘ └─┘  └────┘
pid  ────┘                               └─────────────┘ └─┘       
st   ─────────────────────────────────────────────────────────────────
820  ⟨λ ⟨f⟩, ⟨(f.equiv_lt (order_iso.preimage equiv.ulift r).symm).lt_le
id             └───────┘
src    └┘ └─┘   └───────┘                               └─────────────
typ    └┘└─┘   └───────┘                               └─────────────
doc    └┘ └─┘                                           └─────────────
txt    └┘ └─┘                                           └─────────────
par    └┘ └─┘                                           └─────────────
pid    └┘ └─┘                                           └─────────────
st   ────────────────────────────────────────────────────────────────────
821      (initial_seg.of_iso (order_iso.preimage equiv.ulift s))⟩,
src  ───┘                                                  └────
typ  ───┘                                                  └────
doc  ───┘                                                  └────
txt  ───┘                                                  └────
par  ───┘                                                  └────
pid  ───┘                                                  └────
st   ──────────────────────────────────────────────────────────────
822   λ ⟨f⟩, ⟨(f.equiv_lt (order_iso.preimage equiv.ulift r)).lt_le
id                                                       
src   └┘ └─┘                                           └────────
typ   └┘└─┘                                          └────────
doc   └┘ └─┘                                           └────────
txt   └┘ └─┘                                           └────────
par   └┘ └─┘                                           └────────
pid   └┘ └─┘                                           └────────
st   ───────────────────────────────────────────────────────────────
823      (initial_seg.of_iso (order_iso.preimage equiv.ulift s).symm)⟩⟩
id        └────────────────┘  └────────────────┘ └─────────┘ 
src  ───┘ └────────────────┘ └────────────────┘└─────────┘ └─────────
typ  ───┘ └────────────────┘ └────────────────┘└─────────┘└─────────
doc  ───┘ └────────────────┘ └────────────────┘            └─────────
txt  ───┘                                                  └─────────
par  ───┘                                                  └─────────
pid  ───┘                                                  └───────┘
st   ───────────────────────────────────────────────────────────────────
824  
src  
typ  
doc  
txt  
par  
pid  
st   
825  @[simp] theorem lift_le {a b : ordinal} : lift.{u v} a ≤ lift b ↔ a ≤ b :=
id                                  └─────┘    └──┘         └──┘     
src                                 └─────┘    └──┘          └──┘      
typ                                 └─────┘    └──┘         └──┘     
doc    └──┘                         └─────┘    └──┘           └──┘
826  induction_on a $ λ α r _, induction_on b $ λ β s _,
id   └──────────┘          └──────────┘        
src  └──────────┘              └──────────┘
typ  └──────────┘          └──────────┘        
827  by rw ← lift_umax; exactI lift_type_le
id           └───────┘         └──────────┘
src     └───┘└───────┘  └─────┘└──────────┘
typ     └───┘└───────┘  └─────┘└──────────┘
doc     └───┘           └─────┘            
txt     └───┘           └─────┘            
par     └───┘           └─────┘            
pid       └─┘                             
st     └────────────────────────────────────
828  
src  
typ  
doc  
txt  
par  
pid  
st   
829  @[simp] theorem lift_inj {a b : ordinal} : lift a = lift b ↔ a = b :=
id                                   └─────┘    └──┘   └──┘     
src                                  └─────┘    └──┘    └──┘      
typ                                  └─────┘    └──┘   └──┘     
doc    └──┘                          └─────┘    └──┘     └──┘
830  by simp only [le_antisymm_iff, lift_le]
id                 └─────────────┘  └─────┘
src     └─────────┘└─────────────┘└┘└─────┘└─
typ     └─────────┘└─────────────┘└┘└─────┘└─
doc     └─────────┘               └┘       └─
txt     └─────────┘               └┘       └─
par     └─────────┘               └┘       └─
pid         └──┘└┘               └┘       
st     └─────────────────────────────────────
831  
src  
typ  
doc  
txt  
par  
pid  
st   
832  @[simp] theorem lift_lt {a b : ordinal} : lift a < lift b ↔ a < b :=
id                                  └─────┘    └──┘   └──┘     
src                                 └─────┘    └──┘    └──┘      
typ                                 └─────┘    └──┘   └──┘     
doc    └──┘                         └─────┘    └──┘     └──┘
833  by simp only [lt_iff_le_not_le, lift_le]
id                 └──────────────┘  └─────┘
src     └─────────┘└──────────────┘└┘└─────┘└─
typ     └─────────┘└──────────────┘└┘└─────┘└─
doc     └─────────┘                └┘       └─
txt     └─────────┘                └┘       └─
par     └─────────┘                └┘       └─
pid         └──┘└┘                └┘       
st     └──────────────────────────────────────
834  
src  
typ  
doc  
txt  
par  
pid  
st   
835  @[simp] theorem lift_zero : lift 0 = 0 :=
id                               └──┘   
src                              └──┘   
typ                              └──┘   
doc    └──┘                      └──┘
836  quotient.sound ⟨(order_iso.preimage equiv.ulift _).trans
id   └────────────┘   └────────────────┘ └─────────┘   └───┘
src  └────────────┘   └────────────────┘ └─────────┘   └───┘
typ  └────────────┘   └────────────────┘ └─────────┘   └───┘
doc                   └────────────────┘
837   ⟨pempty_equiv_pempty, λ a b, iff.rfl⟩⟩
id     └─────────────────┘       └─────┘
src    └─────────────────┘         └─────┘
typ    └─────────────────┘       └─────┘
838  
839  theorem zero_eq_lift_type_empty : 0 = lift.{0 u} (@type empty empty_relation _) :=
id                                        └──┘         └──┘ └───┘ └────────────┘
src                                       └──┘         └──┘ └───┘ └────────────┘
typ                                       └──┘         └──┘ └───┘ └────────────┘
doc                                        └──┘         └──┘
840  by rw [← zero_eq_type_empty, lift_zero]
id            └────────────────┘  └───────┘
src     └────┘└────────────────┘└┘└───────┘└─
typ     └────┘└────────────────┘└┘└───────┘└─
doc     └────┘                  └┘         └─
txt     └────┘                  └┘         └─
par     └────┘                  └┘         └─
pid       └──┘                  └┘         
st     └───────────────────────┘└─────────┘
841  
src  
typ  
doc  
txt  
par  
pid  
st   
842  @[simp] theorem lift_one : lift 1 = 1 :=
id                              └──┘   
src                             └──┘   
typ                             └──┘   
doc    └──┘                     └──┘
843  quotient.sound ⟨(order_iso.preimage equiv.ulift _).trans
id   └────────────┘   └────────────────┘ └─────────┘   └───┘
src  └────────────┘   └────────────────┘ └─────────┘   └───┘
typ  └────────────┘   └────────────────┘ └─────────┘   └───┘
doc                   └────────────────┘
844   ⟨punit_equiv_punit, λ a b, iff.rfl⟩⟩
id     └───────────────┘       └─────┘
src    └───────────────┘         └─────┘
typ    └───────────────┘       └─────┘
845  
846  theorem one_eq_lift_type_unit : 1 = lift.{0 u} (@type unit empty_relation _) :=
id                                      └──┘         └──┘ └──┘ └────────────┘
src                                     └──┘         └──┘ └──┘ └────────────┘
typ                                     └──┘         └──┘ └──┘ └────────────┘
doc                                      └──┘         └──┘ └──┘
847  by rw [← one_eq_type_unit, lift_one]
id            └──────────────┘  └──────┘
src     └────┘└──────────────┘└┘└──────┘└─
typ     └────┘└──────────────┘└┘└──────┘└─
doc     └────┘                └┘        └─
txt     └────┘                └┘        └─
par     └────┘                └┘        └─
pid       └──┘                └┘        
st     └─────────────────────┘└────────┘
848  
src  
typ  
doc  
txt  
par  
pid  
st   
849  @[simp] theorem lift_add (a b) : lift (a + b) = lift a + lift b :=
id                                    └──┘       └──┘   └──┘ 
src                                   └──┘         └──┘    └──┘
typ                                   └──┘       └──┘   └──┘ 
doc    └──┘                           └──┘           └──┘     └──┘
850  quotient.induction_on₂ a b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩,
id   └────────────────────┘                
src  └────────────────────┘
typ  └────────────────────┘                
851  quotient.sound ⟨(order_iso.preimage equiv.ulift _).trans
id   └────────────┘   └────────────────┘ └─────────┘   └───┘
src  └────────────┘   └────────────────┘ └─────────┘   └───┘
typ  └────────────┘   └────────────────┘ └─────────┘   └───┘
doc                   └────────────────┘
852   (order_iso.sum_lex_congr (order_iso.preimage equiv.ulift _)
id     └─────────────────────┘  └────────────────┘ └─────────┘
src    └─────────────────────┘  └────────────────┘ └─────────┘
typ    └─────────────────────┘  └────────────────┘ └─────────┘
doc                             └────────────────┘
853     (order_iso.preimage equiv.ulift _)).symm⟩
id       └────────────────┘ └─────────┘    └──┘
src      └────────────────┘ └─────────┘    └──┘
typ      └────────────────┘ └─────────┘    └──┘
doc      └────────────────┘
854  
855  @[simp] theorem lift_succ (a) : lift (succ a) = succ (lift a) :=
id                                   └──┘  └──┘    └──┘  └──┘ 
src                                  └──┘  └──┘     └──┘  └──┘
typ                                  └──┘  └──┘    └──┘  └──┘ 
doc    └──┘                          └──┘  └──┘      └──┘  └──┘
856  by unfold succ; simp only [lift_add, lift_one]
id                              └──────┘  └──────┘
src     └─────────┘  └─────────┘└──────┘└┘└──────┘└─
typ     └─────────┘  └─────────┘└──────┘└┘└──────┘└─
doc     └─────────┘  └─────────┘        └┘        └─
txt     └─────────┘  └─────────┘        └┘        └─
par     └─────────┘  └─────────┘        └┘        └─
pid           └───┘      └──┘└┘        └┘        
st     └────────────────────────────────────────────
857  
src  
typ  
doc  
txt  
par  
pid  
st   
858  @[simp] theorem lift_card (a) : (card a).lift = card (lift a) :=
id                                    └──┘  └──┘   └──┘  └──┘ 
src                                   └──┘   └──┘   └──┘  └──┘
typ                                   └──┘  └──┘   └──┘  └──┘ 
doc    └──┘                           └──┘   └──┘    └──┘  └──┘
859  induction_on a $ λ α r _, rfl
id   └──────────┘          └─┘
src  └──────────┘              └─┘
typ  └──────────┘          └─┘
860  
861  theorem lift_down' {a : cardinal.{u}} {b : ordinal.{max u v}}
id                           └──────┘           └─────┘
src                          └──────┘           └─────┘
typ                          └──────┘           └─────┘
doc                          └──────┘           └─────┘
862    (h : card b ≤ a.lift) : ∃ a', lift a' = b :=
id          └──┘   └───┘     └┘ └──┘ └┘  
src         └──┘     └───┘        └──┘    
typ         └──┘   └───┘     └┘ └──┘ └┘  
doc         └──┘      └───┘          └──┘
863  let ⟨c, e⟩ := cardinal.lift_down h in
id   └─┘         └────────────────┘ 
src                └────────────────┘
typ  └─┘         └────────────────┘ 
864  quotient.induction_on c (λ α, induction_on b $ λ β s _ e', begin
id   └───────────────────┘        └──────────┘         └┘
src  └───────────────────┘         └──────────┘
typ  └───────────────────┘        └──────────┘         └┘
st                                                              └─────
865    resetI,
src    └────┘
typ    └────┘
doc    └────┘
txt    └────┘
par    └────┘
st   ──────────
866    rw [mk_def, card_type, ← cardinal.lift_id'.{(max u v) u} (mk β),
id         └────┘  └───────┘    └───────────────┘                └┘ 
src    └──┘└────┘└┘└───────┘└──┘└───────────────┘└─────────────┘ └┘ └──
typ    └──┘└────┘└┘└───────┘└──┘└───────────────┘└─────────────┘ └┘└──
doc    └──┘      └┘         └──┘                 └─────────────┘ └┘ └──
txt    └──┘      └┘         └──┘                 └─────────────┘    └──
par    └──┘      └┘         └──┘                 └─────────────┘    └──
pid      └┘      └┘         └──┘                 └─────────────┘    └──
st   ───────────┘└─────────┘└────────────────────────────────────────┘└─
867        ← cardinal.lift_umax.{u v}, lift_mk_eq.{u (max u v) (max u v)}] at e',
id           └────────────────┘        └────────┘
src  ───────┘└────────────────┘└──────┘└────────┘└─────────────────────────────┘
typ  ───────┘└────────────────┘└──────┘└────────┘└─────────────────────────────┘
doc  ───────┘                  └──────┘          └─────────────────────────────┘
txt  ───────┘                  └──────┘          └─────────────────────────────┘
par  ───────┘                  └──────┘          └─────────────────────────────┘
pid  ───────┘                  └──────┘          └───────────────────────┘└────┘
st   ───────────────────────────────┘└──────────────────────────────────┘└────┘└─
868    cases e' with f,
id           └┘
src    └────┘  └─────┘
typ    └────┘└┘└─────┘
doc    └────┘  └─────┘
txt    └────┘  └─────┘
par    └────┘  └─────┘
pid           └─────┘
st   ────────────────┘└─
869    have g := order_iso.preimage f s,
id               └────────────────┘  
src    └────────┘└────────────────┘ 
typ    └────────┘└────────────────┘
doc    └────────┘└────────────────┘ 
txt    └────────┘                   
par    └────────┘                   
pid    └────┘└─┘                   
st   ─────────────────────────────────┘└─
870    haveI := g.to_order_embedding.is_well_order,
id              └────────────────────────────────┘
src    └───────┘└────────────────────────────────┘
typ    └───────┘└────────────────────────────────┘
doc    └───────┘
txt    └───────┘
par    └───────┘
pid         └─┘
st   ────────────────────────────────────────────┘└─
871    have := lift_type_eq.{u (max u v) (max u v)}.2 ⟨g⟩,
id             └──────────┘                            
src    └──────┘└──────────┘└─────────────────────────┘  
typ    └──────┘└──────────┘└─────────────────────────┘ 
doc    └──────┘            └─────────────────────────┘  
txt    └──────┘            └─────────────────────────┘  
par    └──────┘            └─────────────────────────┘  
pid    └───┘└─┘            └─────────────────────────┘  
st   ───────────────────────────────────────────────────┘└─
872    rw [lift_id, lift_umax.{u v}] at this,
id         └─────┘  └───────┘
src    └──┘└─────┘└┘└───────┘└─────────────┘
typ    └──┘└─────┘└┘└───────┘└─────────────┘
doc    └──┘       └┘         └─────────────┘
txt    └──┘       └┘         └─────────────┘
par    └──┘       └┘         └─────────────┘
pid      └┘       └┘         └─────┘└──────┘
st   ────────────┘└───────────────┘└──────┘└─
873    exact ⟨_, this⟩
id               └──┘
src    └────┘ └─┘    └┘
typ    └────┘ └─┘└──┘└┘
doc    └────┘ └─┘    └┘
txt    └────┘ └─┘    └┘
par    └────┘ └─┘    └┘
pid          └─┘    
st   ─────────────────┘
874  end) e
st   └─┘
875  
876  theorem lift_down {a : ordinal.{u}} {b : ordinal.{max u v}}
id                          └─────┘           └─────┘
src                         └─────┘           └─────┘
typ                         └─────┘           └─────┘
doc                         └─────┘           └─────┘
877    (h : b ≤ lift a) : ∃ a', lift a' = b :=
id            └──┘      └┘ └──┘ └┘  
src            └──┘          └──┘    
typ           └──┘      └┘ └──┘ └┘  
doc             └──┘            └──┘
878  @lift_down' (card a) _ (by rw lift_card; exact card_le_card h)
id    └────────┘  └──┘            └───────┘        └──────────┘ 
src   └────────┘  └──┘          └─┘└───────┘  └────┘└──────────┘
typ   └────────┘  └──┘         └─┘└───────┘  └────┘└──────────┘
doc               └──┘          └─┘           └────┘            
txt                             └─┘           └────┘            
par                             └─┘           └────┘            
pid                                                           
st                             └─────────────────────────────────┘
879  
880  theorem le_lift_iff {a : ordinal.{u}} {b : ordinal.{max u v}} :
id                            └─────┘           └─────┘
src                           └─────┘           └─────┘
typ                           └─────┘           └─────┘
doc                           └─────┘           └─────┘
881    b ≤ lift a ↔ ∃ a', lift a' = b ∧ a' ≤ a :=
id       └──┘    └┘ └──┘ └┘    └┘  
src       └──┘        └──┘           
typ      └──┘    └┘ └──┘ └┘    └┘  
doc        └──┘           └──┘
882  ⟨λ h, let ⟨a', e⟩ := lift_down h in ⟨a', e, lift_le.1 $ e.symm ▸ h⟩,
id        └─┘  └┘       └───────┘             └─────┘     └───┘  
src                       └───────┘              └─────┘     └───┘ 
typ       └─┘  └┘       └───────┘             └─────┘     └───┘  
883   λ ⟨a', e, h⟩, e ▸ lift_le.2 h⟩
id                  └─────┘
src                    └─────┘
typ                 └─────┘
884  
885  theorem lt_lift_iff {a : ordinal.{u}} {b : ordinal.{max u v}} :
id                            └─────┘           └─────┘
src                           └─────┘           └─────┘
typ                           └─────┘           └─────┘
doc                           └─────┘           └─────┘
886    b < lift a ↔ ∃ a', lift a' = b ∧ a' < a :=
id       └──┘    └┘ └──┘ └┘    └┘  
src       └──┘        └──┘           
typ      └──┘    └┘ └──┘ └┘    └┘  
doc        └──┘           └──┘
887  ⟨λ h, let ⟨a', e⟩ := lift_down (le_of_lt h) in
id        └─┘  └┘       └───────┘  └──────┘ 
src                       └───────┘  └──────┘
typ       └─┘  └┘       └───────┘  └──────┘ 
888        ⟨a', e, lift_lt.1 $ e.symm ▸ h⟩,
id                 └─────┘     └───┘  
src                └─────┘     └───┘ 
typ                └─────┘     └───┘  
889   λ ⟨a', e, h⟩, e ▸ lift_lt.2 h⟩
id                  └─────┘
src                    └─────┘
typ                 └─────┘
890  
891  /-- `ω` is the first infinite ordinal, defined as the order type of `ℕ`. -/
892  def omega : ordinal.{u} := lift $ @type ℕ (<) _
id               └─────┘        └──┘    └──┘  
src              └─────┘        └──┘    └──┘  
typ              └─────┘        └──┘    └──┘  
doc              └─────┘        └──┘    └──┘
893  
894  localized "notation `ω` := ordinal.omega.{0}" in ordinal
895  
896  theorem card_omega : card omega = cardinal.omega := rfl
id                        └──┘ └───┘  └────────────┘    └─┘
src                       └──┘ └───┘  └────────────┘    └─┘
typ                       └──┘ └───┘  └────────────┘    └─┘
doc                       └──┘ └───┘   └────────────┘
897  
898  @[simp] theorem lift_omega : lift omega = omega := lift_lift _
id                                └──┘ └───┘  └───┘    └───────┘
src                               └──┘ └───┘  └───┘    └───────┘
typ                               └──┘ └───┘  └───┘    └───────┘
doc    └──┘                       └──┘ └───┘   └───┘
899  
900  theorem add_le_add_right {a b : ordinal} : a ≤ b → ∀ c, a + c ≤ b + c :=
id                                   └─────┘                   
src                                  └─────┘                        
typ                                  └─────┘                   
doc                                  └─────┘
901  induction_on a $ λ α₁ r₁ hr₁, induction_on b $ λ α₂ r₂ hr₂ ⟨⟨⟨f, fo⟩, fi⟩⟩ c,
id   └──────────┘      └┘ └┘ └─┘  └──────────┘      └┘ └┘ └─┘               
src  └──────────┘                  └──────────┘
typ  └──────────┘      └┘ └┘ └─┘  └──────────┘      └┘ └┘ └─┘               
902  induction_on c $ λ β s hs, (@type_le' _ _ _ _
id   └──────────┘        └┘    └──────┘
src  └──────────┘                 └──────┘
typ  └──────────┘        └┘    └──────┘
903    (@sum.lex.is_well_order _ _ _ _ hr₁ hs)
id       └───────────────────┘         └─┘ └┘
src      └───────────────────┘
typ      └───────────────────┘         └─┘ └┘
904    (@sum.lex.is_well_order _ _ _ _ hr₂ hs)).2
id       └───────────────────┘         └─┘ └┘  
src      └───────────────────┘                 
typ      └───────────────────┘         └─┘ └┘  
905  ⟨⟨embedding.sum_congr f (embedding.refl _), λ a b, begin
id     └─────────────────┘    └────────────┘        
src    └─────────────────┘    └────────────┘
typ    └─────────────────┘    └────────────┘        
st                                                      └─────
906    split; intro H,
src    └───┘  └─────┘
typ    └───┘  └─────┘
doc    └───┘  └─────┘
txt    └───┘  └─────┘
par    └───┘  └─────┘
pid                └┘
st   ───────────────┘└─
907    { cases H; constructor; [rwa ← fo, assumption] },
id                            
src      └────┘   └─────────┘  └────┘    └────────┘
typ      └────┘  └─────────┘  └────┘└┘  └────────┘
doc      └────┘   └─────────┘   └────┘    └────────┘
txt      └────┘   └─────────┘   └────┘    └────────┘
par      └────┘   └─────────┘   └────┘    └────────┘
pid                               └─┘
st   ───┘└──────────────────────────────────────────┘└─┘
908    { cases a with a a; cases b with b b; cases H; constructor; [rwa fo, assumption] }
id                                                              
src      └────┘ └───────┘  └────┘ └───────┘  └────┘   └─────────┘  └──┘    └────────┘
typ      └────┘└───────┘  └────┘└───────┘  └────┘  └─────────┘  └──┘└┘  └────────┘
doc      └────┘ └───────┘  └────┘ └───────┘  └────┘   └─────────┘   └──┘    └────────┘
txt      └────┘ └───────┘  └────┘ └───────┘  └────┘   └─────────┘   └──┘    └────────┘
par      └────┘ └───────┘  └────┘ └───────┘  └────┘   └─────────┘   └──┘    └────────┘
pid            └───────┘        └───────┘                           
st   ──────────────────────────────────────────────────────────────────┘└┘└───────────┘└──
909  end⟩⟩
st   ──┘
910  
911  theorem le_add_left (a b : ordinal) : a ≤ b + a :=
id                              └─────┘        
src                             └─────┘         
typ                             └─────┘        
doc                             └─────┘
912  by simpa only [zero_add] using add_le_add_right (zero_le b) a
id                  └──────┘        └──────────────┘  └─────┘   
src     └──────────┘└──────┘└──────┘└──────────────┘ └─────┘ └┘ 
typ     └──────────┘└──────┘└──────┘└──────────────┘ └─────┘└┘
doc     └──────────┘        └──────┘                         └┘ 
txt     └──────────┘        └──────┘                         └┘ 
par     └──────────┘        └──────┘                         └┘ 
pid          └──┘└┘        └────┘                         └┘ 
st     └───────────────────────────────────────────────────────────
913  
src  
typ  
doc  
txt  
par  
pid  
st   
914  theorem le_total (a b : ordinal) : a ≤ b ∨ b ≤ a :=
id                           └─────┘          
src                          └─────┘            
typ                          └─────┘          
doc                          └─────┘
915  match lt_or_eq_of_le (le_add_left b a), lt_or_eq_of_le (le_add_right a b) with
id         └────────────┘  └─────────┘     └────────────┘  └──────────┘  
src        └────────────┘  └─────────┘       └────────────┘  └──────────┘
typ        └────────────┘  └─────────┘     └────────────┘  └──────────┘  
916  | or.inr h, _ := by rw h; exact or.inl (le_add_right _ _)
id     └────┘                       └────┘  └──────────┘
src    └────┘            └─┘   └────┘└────┘ └──────────┘└────┘
typ    └────┘            └─┘  └────┘└────┘ └──────────┘└────┘
doc                      └─┘   └────┘                   └────┘
txt                      └─┘   └────┘                   └────┘
par                      └─┘   └────┘                   └────┘
pid                                                   └───┘
st                      └─────────────────────────────────────┘
917  | _, or.inr h := by rw h; exact or.inr (le_add_left _ _)
id        └────┘                    └────┘  └─────────┘
src       └────┘         └─┘   └────┘└────┘ └─────────┘└────┘
typ       └────┘         └─┘  └────┘└────┘ └─────────┘└────┘
doc                      └─┘   └────┘                  └────┘
txt                      └─┘   └────┘                  └────┘
par                      └─┘   └────┘                  └────┘
pid                                                  └───┘
st                      └────────────────────────────────────┘
918  | or.inl h₁, or.inl h₂ := induction_on a (λ α₁ r₁ _,
id            └┘  └────┘ └┘    └──────────┘     └┘ └┘ 
src               └────┘       └──────────┘
typ           └┘  └────┘ └┘    └──────────┘     └┘ └┘ 
919    induction_on b $ λ α₂ r₂ _ ⟨f⟩ ⟨g⟩, begin
id     └──────────┘      └┘ └┘     
src    └──────────┘
typ    └──────────┘      └┘ └┘     
st                                         └─────
920      resetI,
src      └────┘
typ      └────┘
doc      └────┘
txt      └────┘
par      └────┘
st   ────────────
921      rw [← typein_top f, ← typein_top g, le_iff_lt_or_eq,
id             └────────┘ 
src      └────┘└────────┘
typ      └────┘└────────┘ 
doc      └────┘
txt      └────┘
par      └────┘
pid        └──┘
st   ───────────────────┘ 
922          le_iff_lt_or_eq, typein_lt_typein, typein_lt_typein],
923      rcases trichotomous_of (sum.lex r₁ r₂) g.top f.top with h|h|h;
id                                     └┘ └┘        
src                                                 
typ                                    └┘ └┘        
doc                              
924      [exact or.inl (or.inl h), {left, right, rw h}, exact or.inr (or.inl h)]
st                                                                             
925    end) h₁ h₂
st   ────┘
926  end
927  
928  instance : decidable_linear_order ordinal :=
id              └────────────────────┘ └─────┘
src             └────────────────────┘ └─────┘
typ             └────────────────────┘ └─────┘
doc                                    └─────┘
929  { le_total     := le_total,
id                     └──────┘
src                    └──────┘
typ                    └──────┘
930    decidable_le := classical.dec_rel _,
id                     └───────────────┘
src                    └───────────────┘
typ                    └───────────────┘
931    ..ordinal.partial_order }
id       └───────────────────┘
src      └───────────────────┘
typ      └───────────────────┘
932  
933  @[simp] lemma typein_le_typein (r : α → α → Prop) [is_well_order α r] {x x' : α} :
id                                                    └───────────┘            
src                                                     └───────────┘
typ                                                   └───────────┘            
doc    └──┘                                             └───────────┘
934    typein r x ≤ typein r x' ↔ ¬r x' x :=
id     └────┘    └────┘  └┘   └┘ 
src    └────┘      └────┘       
typ    └────┘    └────┘  └┘   └┘ 
doc    └────┘       └────┘
935  by rw [←not_lt, typein_lt_typein]
id           └────┘  └──────────────┘
src          └────┘  └──────────────┘
typ          └────┘  └──────────────┘
st          └────┘  └──────────────┘
936  
937  lemma enum_le_enum (r : α → α → Prop) [is_well_order α r] {o o' : ordinal}
id                                        └───────────┘            └─────┘
src                                         └───────────┘              └─────┘
typ                                       └───────────┘            └─────┘
doc                                         └───────────┘              └─────┘
938    (ho : o < type r) (ho' : o' < type r) : ¬r (enum r o' ho') (enum r o ho) ↔ o ≤ o' :=
id             └──┘          └┘  └──┘       └──┘  └┘ └─┘   └──┘   └┘     └┘
src             └──┘               └──┘         └──┘            └──┘            
typ            └──┘          └┘  └──┘       └──┘  └┘ └─┘   └──┘   └┘     └┘
doc              └──┘                └──┘          └──┘            └──┘
939  by rw [←@not_lt _ _ o' o, enum_lt ho']
st                                       
940  
941  theorem lt_succ {a b : ordinal} : a < succ b ↔ a ≤ b :=
id                          └┘  └┘                  
src                         └┘  └┘                
typ                         └┘  └┘                  
doc                         └┘  └┘
942  by rw [← not_le, succ_le, not_lt]
st                                   
943  
944  theorem add_lt_add_iff_left (a) {b c : ordinal} : a + b < a + c ↔ b < c :=
id                                          └┘  └┘                   
src                                         └┘  └┘                   
typ                                         └┘  └┘                   
doc                                         └┘  └┘
945  by rw [← not_le, ← not_le, add_le_add_iff_left]
st                                                 
946  
947  theorem lt_of_add_lt_add_right {a b c : ordinal} : a + b < c + b → a < c :=
id                                           └┘  └┘                     
src                                          └┘  └┘
typ                                          └┘  └┘                     
doc                                          └┘  └┘
948  lt_imp_lt_of_le_imp_le (λ h, add_le_add_right h _)
949  
950  @[simp] theorem succ_lt_succ {a b : ordinal} : succ a < succ b ↔ a < b :=
id                                         └┘                        
src                                        └┘                      
typ                                        └┘                        
doc    └──┘                                └┘  
951  by rw [lt_succ, succ_le]
952  
953  @[simp] theorem succ_le_succ {a b : ordinal} : succ a ≤ succ b ↔ a ≤ b :=
id                                       └┘  └┘                       
src                                      └┘  └┘                     
typ                                      └┘  └┘                       
doc    └──┘                              └┘  └┘
954  le_iff_le_iff_lt_iff_lt.2 succ_lt_succ
955  
956  theorem succ_inj {a b : ordinal} : succ a = succ b ↔ a = b :=
id                            └┘  └┘                      
src                           └┘  └┘                    
typ                           └┘  └┘                      
doc                           └┘  └┘
957  by simp only [le_antisymm_iff, succ_le_succ]
958  
959  theorem add_le_add_iff_right {a b : ordinal} (n : ℕ) : a + n ≤ b + n ↔ a ≤ b :=
id                                       └┘  └┘                          
src                                      └┘  └┘                          
typ                                      └┘  └┘                          
doc                                      └┘  └┘
960  by induction n with n ih; [rw [nat.cast_zero, add_zero, add_zero],
st                                                                   
961    rw [← nat_cast_succ, add_succ, add_succ, succ_le_succ, ih]]
st                                                              
962  
963  theorem add_right_cancel {a b : ordinal} (n : ℕ) : a + n = b + n ↔ a = b :=
id                                   └┘  └┘                          
src                                  └┘  └┘                          
typ                                  └┘  └┘                          
doc                                  └┘  └┘
964  by simp only [le_antisymm_iff, add_le_add_iff_right]
965  
966  @[simp] theorem card_eq_zero {o} : card o = 0 ↔ o = 0 :=
id                                                 
src                                                
typ                                                
doc    └──┘
967  ⟨induction_on o $ λ α r _ h, begin
id                       
typ                      
968    refine le_antisymm (le_of_not_lt $
969      λ hn, ne_zero_iff_nonempty.2 _ h) (zero_le _),
970    rw [← succ_le, succ_zero] at hn, cases hn with f,
971    exact ⟨f punit.star⟩
id              └────────┘
src             └────────┘
typ             └────────┘
972  end, λ e, by simp only [e, card_zero]⟩
st   └─┘
973  
974  @[simp] theorem type_ne_zero_iff_nonempty [is_well_order α r] : type r ≠ 0 ↔ nonempty α :=
id                                                                             └┘  └┘  
src                                                                               └┘  └┘
typ                                                                            └┘  └┘  
doc    └──┘
975  (not_congr (@card_eq_zero (type r))).symm.trans ne_zero_iff_nonempty
id                                   
typ                                  
976  
977  @[simp] theorem type_eq_zero_iff_empty [is_well_order α r] : type r = 0 ↔ ¬ nonempty α :=
id                                                                           └┘  └┘  
src                                                                             └┘  └┘
typ                                                                          └┘  └┘  
doc    └──┘
978  (not_iff_comm.1 type_ne_zero_iff_nonempty).symm
979  
980  instance : zero_ne_one_class ordinal.{u} :=
id                                └──┘  
src                               └──┘  
typ                               └──┘  
doc                               └──┘  
981  { zero := 0, one := 1, zero_ne_one :=
982    ne.symm $ type_ne_zero_iff_nonempty.2 ⟨punit.star⟩ }
id                                            └───┘ └──┘
src                                           └───┘ └──┘
typ                                           └───┘ └──┘
983  
984  theorem zero_lt_one : (0 : ordinal) < 1 :=
id                                └──┘
src                               └──┘
typ                               └──┘
doc                               └──┘
985  lt_iff_le_and_ne.2 ⟨zero_le _, zero_ne_one⟩
986  
987  /-- The ordinal predecessor of `o` is `o'` if `o = succ o'`,
988    and `o` otherwise. -/
989  def pred (o : ordinal.{u}) : ordinal.{u} :=
id                 └┘  └─┘          └──┘
src                └┘  └─┘          └──┘
typ                └┘  └─┘          └──┘
doc                └┘  └─┘          └──┘
990  if h : ∃ a, o = succ a then classical.some h else o
id                      
typ                     
991  
992  @[simp] theorem pred_succ (o) : pred (succ o) = o :=
id                                                  
typ                                                 
doc    └──┘
993  by have h : ∃ a, succ o = succ a := ⟨_, rfl⟩;
id                        
typ                       
994     simpa only [pred, dif_pos h] using (succ_inj.1 $ classical.some_spec h).symm
id                  └──┘
src                 └──┘
typ                 └──┘
doc                 └──┘
995  
996  theorem pred_le_self (o) : pred o ≤ o :=
id                                      
typ                                     
997  if h : ∃ a, o = succ a then let ⟨a, e⟩ := h in
id                      
typ                     
998  by rw [e, pred_succ]; exact le_of_lt (lt_succ_self _)
999  else by rw [pred, dif_neg h]
st                              
1000  
1001  theorem pred_eq_iff_not_succ {o} : pred o = o ↔ ¬ ∃ a, o = succ a :=
id                                                             
src                                                 
typ                                                            
1002  ⟨λ e ⟨a, e'⟩, by rw [e', pred_succ] at e; exact ne_of_lt (lt_succ_self _) e,
1003   λ h, dif_neg h⟩
1004  
1005  theorem pred_lt_iff_is_succ {o} : pred o < o ↔ ∃ a, o = succ a :=
id                                                           
src                                               
typ                                                          
1006  iff.trans (by simp only [le_antisymm_iff, pred_le_self, true_and, not_le])
1007    (iff_not_comm.1 pred_eq_iff_not_succ).symm
1008  
1009  theorem succ_pred_iff_is_succ {o} : succ (pred o) = o ↔ ∃ a, o = succ a :=
id                                                                    
src                                                        
typ                                                                   
1010  ⟨λ e, ⟨_, e.symm⟩, λ ⟨a, e⟩, by simp only [e, pred_succ]⟩
1011  
1012  theorem succ_lt_of_not_succ {o} (h : ¬ ∃ a, o = succ a) {b} : succ b < o ↔ b < o :=
id                                                                          
src                                                                          
typ                                                                         
1013  ⟨lt_trans (lt_succ_self _), λ l,
1014    lt_of_le_of_ne (succ_le.2 l) (λ e, h ⟨_, e.symm⟩)⟩
1015  
1016  theorem lt_pred {a b} : a < pred b ↔ succ a < b :=
id                                             
src                                     
typ                                            
1017  if h : ∃ a, b = succ a then let ⟨c, e⟩ := h in
id                      
typ                     
1018  by rw [e, pred_succ, succ_lt_succ]
st                                    
1019  else by simp only [pred, dif_neg h, succ_lt_of_not_succ h]
id                      └──┘
src                     └──┘
typ                     └──┘
doc                     └──┘
1020  
1021  theorem pred_le {a b} : pred a ≤ b ↔ a ≤ succ b :=
id                                             
src                                     
typ                                            
1022  le_iff_le_iff_lt_iff_lt.2 lt_pred
1023  
1024  @[simp] theorem lift_is_succ {o} : (∃ a, lift o = succ a) ↔ (∃ a, o = succ a) :=
id                                                                        
src                                                            
typ                                                                       
doc    └──┘
1025  ⟨λ ⟨a, h⟩,
1026    let ⟨b, e⟩ := lift_down $ show a ≤ lift o, from le_of_lt $
id                                            
typ                                           
1027      h.symm ▸ lt_succ_self _ in
1028    ⟨b, lift_inj.1 $ by rw [h, ← e, lift_succ]⟩,
st                                              
1029   λ ⟨a, h⟩, ⟨lift a, by simp only [h, lift_succ]⟩⟩
id       
typ      
1030  
1031  @[simp] theorem lift_pred (o) : lift (pred o) = pred (lift o) :=
id                                                             
typ                                                            
doc    └──┘
1032  if h : ∃ a, o = succ a then
id                      
typ                     
1033  by cases h with a e; simp only [e, pred_succ, lift_succ]
1034  else by rw [pred_eq_iff_not_succ.2 h,
1035              pred_eq_iff_not_succ.2 (mt lift_is_succ.1 h)]
st                                                           
1036  
1037  /-- A limit ordinal is an ordinal which is not zero and not a successor. -/
1038  def is_limit (o : ordinal) : Prop := o ≠ 0 ∧ ∀ a < o, succ a < o
id                     └┘  └─┘                                  
src                    └┘  └─┘                  
typ                    └┘  └─┘                                  
doc                    └┘  └─┘
1039  
1040  theorem not_zero_is_limit : ¬ is_limit 0
1041  | ⟨h, _⟩ := h rfl
1042  
1043  theorem not_succ_is_limit (o) : ¬ is_limit (succ o)
id                                                    
typ                                                   
1044  | ⟨_, h⟩ := lt_irrefl _ (h _ (lt_succ_self _))
1045  
1046  theorem not_succ_of_is_limit {o} (h : is_limit o) : ¬ ∃ a, o = succ a
id                                           └┘                     
src                                          └┘  
typ                                          └┘                     
doc                                          └┘  
1047  | ⟨a, e⟩ := not_succ_is_limit a (e ▸ h)
id                                       
typ                                      
1048  
1049  theorem succ_lt_of_is_limit {o} (h : is_limit o) {a} : succ a < o ↔ a < o :=
id                                          └┘                        
src                                         └┘                       
typ                                         └┘                        
doc                                         └┘  
1050  ⟨lt_trans (lt_succ_self _), h.2 _⟩
id                               
typ                              
1051  
1052  theorem le_succ_of_is_limit {o} (h : is_limit o) {a} : o ≤ succ a ↔ o ≤ a :=
id                                          └┘  └┘                      
src                                         └┘  └┘                     
typ                                         └┘  └┘                      
doc                                         └┘  └┘
1053  le_iff_le_iff_lt_iff_lt.2 $ succ_lt_of_is_limit h
id                                                   
typ                                                  
1054  
1055  theorem limit_le {o} (h : is_limit o) {a} : o ≤ a ↔ ∀ x < o, x ≤ a :=
id                               └┘  └┘                         
src                              └┘  └┘                
typ                              └┘  └┘                         
doc                              └┘  └┘
1056  ⟨λ h x l, le_trans (le_of_lt l) h,
id        
typ       
1057   λ H, (le_succ_of_is_limit h).1 $ le_of_not_lt $ λ hn,
id                              
typ                             
1058    not_lt_of_le (H _ hn) (lt_succ_self _)⟩
1059  
1060  theorem lt_limit {o} (h : is_limit o) {a} : a < o ↔ ∃ x < o, a < x :=
id                              └┘  └┘                         
src                             └┘  └┘                 
typ                             └┘  └┘                         
doc                             └┘  └┘
1061  by simpa only [not_ball, not_le] using not_congr (@limit_le _ h a)
id                                                                  
typ                                                                 
1062  
1063  @[simp] theorem lift_is_limit (o) : is_limit (lift o) ↔ is_limit o :=
id                                                          └┘  └┘  
src                                                          └┘  └┘
typ                                                         └┘  └┘  
doc    └──┘                                                   └┘  └┘
1064  and_congr (not_congr $ by simpa only [lift_zero] using @lift_inj o 0)
id                                                                    
typ                                                                   
1065  ⟨λ H a h, lift_lt.1 $ by simpa only [lift_succ] using H _ (lift_lt.2 h),
id        
typ       
1066   λ H a h, let ⟨a', e⟩ := lift_down (le_of_lt h) in
id        
typ       
1067     by rw [← e, ← lift_succ, lift_lt];
1068        rw [← e, lift_lt] at h; exact H a' h⟩
id                                         └┘
typ                                        └┘
1069  
1070  theorem is_limit.pos {o : ordinal} (h : is_limit o) : 0 < o :=
id                             └──┘          └┘  └┘          
src                            └──┘          └┘  └┘
typ                            └──┘          └┘  └┘          
doc                            └──┘          └┘  └┘
1071  lt_of_le_of_ne (zero_le _) h.1.symm
id                              
typ                             
1072  
1073  theorem is_limit.one_lt {o : ordinal} (h : is_limit o) : 1 < o :=
id                                └┘  └─┘         └┘  └┘         
src                               └┘  └─┘         └┘  └┘
typ                               └┘  └─┘         └┘  └┘         
doc                               └┘  └─┘         └┘  └┘
1074  by simpa only [succ_zero] using h.2 _ h.pos
1075  
1076  theorem is_limit.nat_lt {o : ordinal} (h : is_limit o) : ∀ n : ℕ, (n : ordinal) < o
id                                └──┘          └┘  └┘                  └┘  └┘     
src                               └──┘          └┘  └┘                    └┘  └┘
typ                               └──┘          └┘  └┘                  └┘  └┘     
doc                               └──┘          └┘  └┘                     └┘  └┘
1077  | 0     := h.pos
1078  | (n+1) := h.2 _ (is_limit.nat_lt n)
id             
typ            
1079  
1080  theorem zero_or_succ_or_limit (o : ordinal) :
id                                      └──┘  
src                                     └──┘  
typ                                     └──┘  
doc                                     └──┘  
1081    o = 0 ∨ (∃ a, o = succ a) ∨ is_limit o :=
id                             └┘  └┘
src                                └┘  └┘
typ                            └┘  └┘
doc                                  └┘  └┘
1082  if o0 : o = 0 then or.inl o0 else
id           
typ          
1083  if h : ∃ a, o = succ a then or.inr (or.inl h) else
id                      
typ                     
1084  or.inr $ or.inr ⟨o0, λ a, (succ_lt_of_not_succ h).2⟩
1085  
1086  instance : is_well_order ordinal (<) := ⟨wf⟩
id                            └──┘  
src                           └──┘  
typ                           └──┘  
doc                           └──┘  
1087  
1088  @[elab_as_eliminator] def limit_rec_on {C : ordinal → Sort*}
id                                               └┘  └┘
src                                              └┘  └┘
typ                                              └┘  └┘
doc    └────────────────┘                        └┘  └┘
1089    (o : ordinal) (H₁ : C 0) (H₂ : ∀ o, C o → C (succ o))
id            └──┘                                  
src           └──┘
typ           └──┘                                  
doc           └──┘
1090    (H₃ : ∀ o, is_limit o → (∀ o' < o, C o') → C o) : C o :=
id                                       └┘          
typ                                      └┘          
1091  wf.fix (λ o IH,
id             
typ            
1092    if o0 : o = 0 then by rw o0; exact H₁ else
id             
typ            
1093    if h : ∃ a, o = succ a then
id                        
typ                       
1094      by rw ← succ_pred_iff_is_succ.2 h; exact
1095      H₂ _ (IH _ $ pred_lt_iff_is_succ.2 h)
1096    else H₃ _ ⟨o0, λ a, (succ_lt_of_not_succ h).2⟩ IH) o
id                                                       
typ                                                      
1097  
1098  @[simp] theorem limit_rec_on_zero {C} (H₁ H₂ H₃) : @limit_rec_on C 0 H₁ H₂ H₃ = H₁ :=
id                                                                    
typ                                                                   
doc    └──┘
1099  by rw [limit_rec_on, well_founded.fix_eq, dif_pos rfl]; refl
id                                                           └──┘
src                                                          └──┘
typ                                                          └──┘
doc                                                          └──┘
1100  
1101  @[simp] theorem limit_rec_on_succ {C} (o H₁ H₂ H₃) :
doc    └──┘
1102    @limit_rec_on C (succ o) H₁ H₂ H₃ = H₂ o (@limit_rec_on C o H₁ H₂ H₃) :=
id                                                           
typ                                                          
1103  begin
1104    have h : ∃ a, succ o = succ a := ⟨_, rfl⟩,
id                       
typ                      
1105    rw [limit_rec_on, well_founded.fix_eq,
1106        dif_neg (succ_ne_zero o), dif_pos h],
id                               
typ                              
1107    generalize : limit_rec_on._proof_2 (succ o) h = h₂,
id                                         └──┘ 
src                                        └──┘
typ                                        └──┘ 
doc                                        └──┘
1108    generalize : limit_rec_on._proof_3 (succ o) h = h₃,
id                                         └──┘ 
src                                        └──┘
typ                                        └──┘ 
doc                                        └──┘
1109    revert h₂ h₃, generalize e : pred (succ o) = o', intros,
id                                  └──┘  └──┘ 
src                                 └──┘  └──┘
typ                                 └──┘  └──┘ 
doc                                 └──┘  └──┘
1110    rw pred_succ at e, subst o', refl
id                              └┘
typ                             └┘
1111  end
st   └─┘
1112  
1113  @[simp] theorem limit_rec_on_limit {C} (o H₁ H₂ H₃ h) :
doc    └──┘
1114    @limit_rec_on C o H₁ H₂ H₃ = H₃ o h (λ x h, @limit_rec_on C x H₁ H₂ H₃) :=
id                                                           
typ                                                          
1115  by rw [limit_rec_on, well_founded.fix_eq,
1116         dif_neg h.1, dif_neg (not_succ_of_is_limit h)]; refl
id                                                        └──┘
src                                                         └──┘
typ                                                       └──┘
doc                                                         └──┘
1117  
1118  lemma has_succ_of_is_limit {α} {r : α → α → Prop} [wo : is_well_order α r]
id                                                                        
typ                                                                       
1119    (h : (type r).is_limit) (x : α) : ∃y, r x y :=
id                  └───┘                  
src                  └───┘ 
typ                 └───┘                  
doc                  └───┘ 
1120  begin
1121    use enum r (typein r x).succ (h.2 _ (typein_lt_type r x)),
1122    convert (enum_lt (typein_lt_type r x) _).mpr (lt_succ_self _), rw [enum_typein]
id                                       
typ                                      
st                                                                                   
1123  end
st   └─┘
1124  
1125  lemma type_subrel_lt (o : ordinal.{u}) :
id                             └──┘  
src                            └──┘  
typ                            └──┘  
doc                            └──┘  
1126    type (subrel (<) {o' : ordinal | o' < o}) = ordinal.lift.{u u+1} o :=
id                            └┘  └┘    └┘                             
src                           └┘  └┘
typ                           └┘  └┘    └┘                             
doc                           └┘  └┘
1127  begin
1128    refine quotient.induction_on o _,
1129    rintro ⟨α, r, wo⟩, resetI, apply quotient.sound,
1130    constructor, symmetry, refine (order_iso.preimage equiv.ulift r).trans (typein_iso r)
1131  end
st   └─┘
1132  
1133  lemma mk_initial_seg (o : ordinal.{u}) :
id                             └──┘  
src                            └──┘  
typ                            └──┘  
doc                            └──┘  
1134    #{o' : ordinal | o' < o} = cardinal.lift.{u u+1} o.card :=
id             └┘     └┘                             └┘ └┘
src            └┘                                      └┘ └┘
typ            └┘     └┘                             └┘ └┘
doc            └┘                                      └┘ └┘
1135  by rw [lift_card, ←type_subrel_lt, card_type]
st                                               
1136  
1137  /-- A normal ordinal function is a strictly increasing function which is
1138    order-continuous. -/
1139  def is_normal (f : ordinal → ordinal) : Prop :=
id                      └┘  └┘     └┘ └┘
src                     └┘  └┘     └┘ └┘
typ                     └┘  └┘     └┘ └┘
doc                     └┘  └┘     └┘ └┘
1140  (∀ o, f o < f (succ o)) ∧ ∀ o, is_limit o → ∀ a, f o ≤ a ↔ ∀ b < o, f b ≤ a
id                                                               
src                                                          
typ                                                              
1141  
1142  theorem is_normal.limit_le {f} (H : is_normal f) : ∀ {o}, is_limit o →
id                                                                    
typ                                                                   
1143    ∀ {a}, f o ≤ a ↔ ∀ b < o, f b ≤ a := H.2
id                                  
src                   
typ                                 
1144  
1145  theorem is_normal.limit_lt {f} (H : is_normal f) {o} (h : is_limit o) {a} :
id                                                             └┘  └┘  
src                                                             └┘  └┘
typ                                                            └┘  └┘  
doc                                                             └┘  └┘
1146    a < f o ↔ ∃ b < o, a < f b :=
id                       
typ                      
1147  not_iff_not.1 $ by simpa only [exists_prop, not_exists, not_and, not_lt] using H.2 _ h a
id                                                                                        
typ                                                                                       
1148  
1149  theorem is_normal.lt_iff {f} (H : is_normal f) {a b} : f a < f b ↔ a < b :=
id                                                                    
typ                                                                   
1150  strict_mono.lt_iff_lt $ λ a b,
id                              
typ                             
1151  limit_rec_on b (not.elim (not_lt_of_le $ zero_le _))
id                
typ               
1152    (λ b IH h, (lt_or_eq_of_le (lt_succ.1 h)).elim
id        
typ       
1153      (λ h, lt_trans (IH h) (H.1 _))
id                              
typ                             
1154      (λ e, e ▸ H.1 _))
id                
typ               
1155    (λ b l IH h, lt_of_lt_of_le (H.1 a)
1156      ((H.2 _ l _).1 (le_refl _) _ (l.2 _ h)))
id                                   
typ                                  
1157  
1158  theorem is_normal.le_iff {f} (H : is_normal f) {a b} : f a ≤ f b ↔ a ≤ b :=
id                                                                    
typ                                                                   
1159  le_iff_le_iff_lt_iff_lt.2 H.lt_iff
id                             
typ                            
1160  
1161  theorem is_normal.inj {f} (H : is_normal f) {a b} : f a = f b ↔ a = b :=
id                                                                 
typ                                                                
1162  by simp only [le_antisymm_iff, H.le_iff]
1163  
1164  theorem is_normal.le_self {f} (H : is_normal f) (a) : a ≤ f a :=
id                                                            
typ                                                           
1165  limit_rec_on a (zero_le _)
id                
typ               
1166    (λ a IH, succ_le.2 $ lt_of_le_of_lt IH (H.1 _))
id                                            
typ                                           
1167    (λ a l IH, (limit_le l).2 $ λ b h,
id                         
typ                        
1168      le_trans (IH b h) $ H.le_iff.2 $ le_of_lt h)
id                    
typ                   
1169  
1170  theorem is_normal.le_set {f} (H : is_normal f) (p : ordinal → Prop)
id                                                       └┘  └┘
src                                                       └┘  └┘
typ                                                      └┘  └┘
doc                                                       └┘  └┘
1171    (p0 : ∃ x, p x) (S)
id                
typ               
1172    (H₂ : ∀ o, S ≤ o ↔ ∀ a, p a → a ≤ o) {o} :
id                                 
src                     
typ                                
1173    f S ≤ o ↔ ∀ a, p a → f a ≤ o :=
id                         
typ                        
1174  ⟨λ h a pa, le_trans (H.le_iff.2 ((H₂ _).1 (le_refl _) _ pa)) h,
id                                                         └┘
typ                                                        └┘
1175  λ h, begin
1176    revert H₂, apply limit_rec_on S,
id                                   
typ                                  
1177    { intro H₂,
1178       cases p0 with x px,
1179       have := le_zero.1 ((H₂ _).1 (zero_le _) _ px),
id                                                  └┘
typ                                                 └┘
1180       rw this at px, exact h _ px },
st                                    └┘
1181    { intros S _ H₂,
1182      rcases not_ball.1 (mt (H₂ S).2 $ not_le_of_lt $ lt_succ_self _) with ⟨a, h₁, h₂⟩,
id                                 
typ                                
1183      exact le_trans (H.le_iff.2 $ succ_le.2 $ not_le.1 h₂) (h _ h₁) },
id                                                                  └┘
typ                                                                 └┘
st                                                                      └┘
1184    { intros S L _ H₂, apply (H.2 _ L _).2, intros a h',
id                                    
typ                                   
1185      rcases not_ball.1 (mt (H₂ a).2 (not_le.2 h')) with ⟨b, h₁, h₂⟩,
id                                 
typ                                
1186      exact le_trans (H.le_iff.2 $ le_of_lt $ not_le.1 h₂) (h _ h₁) }
id                                                                 └┘
typ                                                                └┘
st                                                                     └─
1187  end⟩
st   ──┘
1188  
1189  theorem is_normal.le_set' {f} (H : is_normal f) (p : α → Prop) (g : α → ordinal)
id                                                                          └──┘
src                                                                            └──┘
typ                                                                         └──┘
doc                                                                            └──┘
1190    (p0 : ∃ x, p x) (S)
id                
typ               
1191    (H₂ : ∀ o, S ≤ o ↔ ∀ a, p a → g a ≤ o) {o} :
id                                 
src                     
typ                                
1192    f S ≤ o ↔ ∀ a, p a → f (g a) ≤ o :=
id                              
typ                             
1193  (H.le_set (λ x, ∃ y, p y ∧ x = g y)
id                              
typ                             
1194    (let ⟨x, px⟩ := p0 in ⟨_, _, px, rfl⟩) _
id               
typ              
1195    (λ o, (H₂ o).trans ⟨λ H a ⟨y, h1, h2⟩, h2.symm ▸ H y h1,
id                               └┘
typ                              └┘
1196      λ H a h1, H (g a) ⟨a, h1, rfl⟩⟩)).trans
id            └┘           └┘
typ           └┘           └┘
1197  ⟨λ H a h, H (g a) ⟨a, h, rfl⟩, λ H a ⟨y, h1, h2⟩, h2.symm ▸ H y h1⟩
id                                    └┘
typ                                   └┘
1198  
1199  theorem is_normal.refl : is_normal id :=
1200  ⟨λ x, lt_succ_self _, λ o l a, limit_le l⟩
id                                       
typ                                      
1201  
1202  theorem is_normal.trans {f g} (H₁ : is_normal f) (H₂ : is_normal g) :
id                                                                   
typ                                                                  
1203    is_normal (λ x, f (g x)) :=
id                       
typ                      
1204  ⟨λ x, H₁.lt_iff.2 (H₂.1 _),
id        └┘           └┘
typ       └┘           └┘
1205   λ o l a, H₁.le_set' (< o) g ⟨_, l.pos⟩ _ (λ c, H₂.2 _ l _)⟩
id                                             └┘     
typ                                            └┘     
1206  
1207  theorem is_normal.is_limit {f} (H : is_normal f) {o} (l : is_limit o) :
id                                                             └┘  └┘  
src                                                             └┘  └┘
typ                                                            └┘  └┘  
doc                                                             └┘  └┘
1208    is_limit (f o) :=
id      └┘  └┘     
src     └┘  └┘
typ     └┘  └┘     
doc     └┘  └┘
1209  ⟨ne_of_gt $ lt_of_le_of_lt (zero_le _) $ H.lt_iff.2 l.pos,
id                                                      
typ                                                     
1210  λ a h, let ⟨b, h₁, h₂⟩ := (H.limit_lt l).1 h in
id                                       
typ                                      
1211    lt_of_le_of_lt (succ_le.2 h₂) (H.lt_iff.2 h₁)⟩
id                                    
typ                                   
1212  
1213  theorem add_le_of_limit {a b c : ordinal.{u}}
id                                    └┘  └┘
src                                   └┘  └┘
typ                                   └┘  └┘
doc                                   └┘  └┘
1214    (h : is_limit b) : a + b ≤ c ↔ ∀ b' < b, a + b' ≤ c :=
id            └┘                           └┘   
src           └┘                  
typ           └┘                           └┘   
doc           └┘  
1215  ⟨λ h b' l, le_trans (add_le_add_left (le_of_lt l) _) h,
id        └┘
typ       └┘
1216  λ H, le_of_not_lt $
1217  induction_on a (λ α r _, induction_on b $ λ β s _ h H l, begin
id                                             
typ                                            
1218    resetI,
1219    suffices : ∀ x : β, sum.lex r s (sum.inr x) (enum _ _ l),
id                                 
typ                                
1220    { cases enum _ _ l with x x,
1221      { cases this (enum s 0 h.pos) },
id                          
typ                         
st                                     └┘
1222      { exact irrefl _ (this _) } },
st                                 └──┘
1223    intros x,
1224    rw [← typein_lt_typein (sum.lex r s), typein_enum],
id                                      
typ                                     
1225    have := H _ (h.2 _ (typein_lt_type s x)),
id                                         
typ                                        
1226    rw [add_succ, succ_le] at this,
1227    refine lt_of_le_of_lt (type_le'.2
1228      ⟨order_embedding.of_monotone (λ a, _) (λ a b, _)⟩) this,
1229    { rcases a with ⟨a | b, h⟩,
1230      { exact sum.inl a },
id                       
typ                      
st                         └┘
1231      { exact sum.inr ⟨b, by cases h; assumption⟩ } },
id                        
typ                       
st                                                   └──┘
1232    { rcases a with ⟨a | a, h₁⟩; rcases b with ⟨b | b, h₂⟩; cases h₁; cases h₂;
1233        rintro ⟨⟩; constructor; assumption }
id                    └─────────┘  └────────┘
src                   └─────────┘  └────────┘
typ                   └─────────┘  └────────┘
doc                   └─────────┘  └────────┘
st                                            └─
1234  end) h H⟩
id        
typ       
st   ──┘
1235  
1236  theorem add_is_normal (a : ordinal) : is_normal ((+) a) :=
id                              └──┘                     
src                             └──┘  
typ                             └──┘                     
doc                             └──┘  
1237  ⟨λ b, (add_lt_add_iff_left a).2 (lt_succ_self _),
id                             
typ                            
1238   λ b l c, add_le_of_limit l⟩
id                           
typ                          
1239  
1240  theorem add_is_limit (a) {b} : is_limit b → is_limit (a + b) :=
id                                              └┘  └┘       
src                                              └┘  └┘
typ                                             └┘  └┘       
doc                                              └┘  └┘
1241  (add_is_normal a).is_limit
id                  
typ                 
1242  
1243  def typein.principal_seg {α : Type u} (r : α → α → Prop) [is_well_order α r] :
id                                                                          
typ                                                                         
1244    @principal_seg α ordinal.{u} r (<) :=
id                     └┘  └┘      
src                     └┘  └┘
typ                    └┘  └┘      
doc                     └┘  └┘
1245  ⟨order_embedding.of_monotone (typein r)
id                                        
typ                                       
1246    (λ a b, (typein_lt_typein r).2), type r, λ b,
id                                             
typ                                            
1247      ⟨λ h, ⟨enum r _ h, typein_enum r h⟩,
id                                     
typ                                    
1248      λ ⟨a, e⟩, e ▸ typein_lt_type _ _⟩⟩
1249  
1250  @[simp] theorem typein.principal_seg_coe (r : α → α → Prop) [is_well_order α r] :
id                                                                             
typ                                                                            
doc    └──┘
1251    (typein.principal_seg r : α → ordinal) = typein r := rfl
id                                  └┘  └┘           
src                                   └┘  └┘
typ                                 └┘  └┘           
doc                                   └┘  └┘
1252  
1253  /-- The minimal element of a nonempty family of ordinals -/
1254  def min {ι} (I : nonempty ι) (f : ι → ordinal) : ordinal :=
id                     └┘  └┘              └──┘      └──┘
src                    └┘  └┘                └──┘      └──┘
typ                    └┘  └┘              └──┘      └──┘
doc                                          └──┘      └──┘
1255  wf.min (set.range f) (let ⟨i⟩ := I in ⟨_, set.mem_range_self i⟩)
id                                  
typ                                 
1256  
1257  theorem min_eq {ι} (I) (f : ι → ordinal) : ∃ i, min I f = f i :=
id                                   └┘ └┘                  
src                                   └┘ └┘
typ                                  └┘ └┘                  
doc                                   └┘ └┘
1258  let ⟨i, e⟩ := wf.min_mem (set.range f) _ in ⟨i, e.symm⟩
id                                      
typ                                     
1259  
1260  theorem min_le {ι I} (f : ι → ordinal) (i) : min I f ≤ f i :=
id                                  └──┘                 
src                                  └──┘
typ                                 └──┘                 
doc                                  └──┘
1261  le_of_not_gt $ wf.not_lt_min (set.range f) _ (set.mem_range_self i)
id                                                                   
typ                                                                  
1262  
1263  theorem le_min {ι I} {f : ι → ordinal} {a} : a ≤ min I f ↔ ∀ i, a ≤ f i :=
id                                 └┘ └┘                            
src                                 └┘ └┘
typ                                └┘ └┘                            
doc                                 └┘ └┘
1264  ⟨λ h i, le_trans h (min_le _ _),
id        
typ       
1265   λ h, let ⟨i, e⟩ := min_eq I f in e.symm ▸ h i⟩
id                             
typ                            
1266  
1267  /-- The minimal element of a nonempty set of ordinals -/
1268  def omin (S : set ordinal.{u}) (H : ∃ x, x ∈ S) : ordinal.{u} :=
id                     └──┘                          └──┘
src                    └──┘                             └──┘
typ                    └──┘                          └──┘
doc                    └──┘                             └──┘
1269  @min.{(u+2) u} S (let ⟨x, px⟩ := H in ⟨⟨x, px⟩⟩) subtype.val
id                         
typ                        
1270  
1271  theorem omin_mem (S H) : omin S H ∈ S :=
id                                      
typ                                     
1272  let ⟨⟨i, h⟩, e⟩ := @min_eq S _ _ in
id                             
typ                            
1273  (show omin S H = i, from e).symm ▸ h
id              
typ             
1274  
1275  theorem le_omin {S H a} : a ≤ omin S H ↔ ∀ i ∈ S, a ≤ i :=
id                                                    
src                                         
typ                                                   
1276  le_min.trans set_coe.forall
1277  
1278  theorem omin_le {S H i} (h : i ∈ S) : omin S H ≤ i :=
id                                                 
typ                                                
1279  le_omin.1 (le_refl _) _ h
1280  
1281  @[simp] theorem lift_min {ι} (I) (f : ι → ordinal) : lift (min I f) = min I (lift ∘ f) :=
id                                             └┘ └┘                                 
src                                             └┘ └┘
typ                                            └┘ └┘                                 
doc    └──┘                                     └┘ └┘
1282  le_antisymm (le_min.2 $ λ a, lift_le.2 $ min_le _ a) $
id                                                    
typ                                                   
1283  let ⟨i, e⟩ := min_eq I (lift ∘ f) in
id                                 
typ                                
1284  by rw e; exact lift_le.2 (le_min.2 $ λ j, lift_le.1 $
id                                          
typ                                         
1285  by have := min_le (lift ∘ f) j; rwa e at this)
id                      └──┘     
src                     └──┘
typ                     └──┘     
doc                     └──┘
1286  
1287  def lift.initial_seg : @initial_seg ordinal.{u} ordinal.{max u v} (<) (<) :=
id                                       └──┘        └┘  └┘
src                                      └──┘        └┘  └┘
typ                                      └──┘        └┘  └┘
doc                                      └──┘        └┘  └┘
1288  ⟨⟨⟨lift.{u v}, λ a b, lift_inj.1⟩, λ a b, lift_lt.symm⟩,
id                                       
typ                                      
1289    λ a b h, lift_down (le_of_lt h)⟩
id       
typ      
1290  
1291  @[simp] theorem lift.initial_seg_coe : (lift.initial_seg : ordinal → ordinal) = lift := rfl
id                                                              └┘  └┘      └┘
src                                                             └┘  └┘      └┘
typ                                                             └┘  └┘      └┘
doc    └──┘                                                     └┘  └┘      └┘
1292  
1293  /-- `univ.{u v}` is the order type of the ordinals of `Type u` as a member
1294    of `ordinal.{v}` (when `u < v`). It is an inaccessible cardinal. -/
1295  def univ := lift.{(u+1) v} (@type ordinal.{u} (<) _)
id                                     └──┘  
src                                    └──┘  
typ                                    └──┘  
doc                                    └──┘  
1296  
1297  theorem univ_id : univ.{u (u+1)} = @type ordinal.{u} (<) _ := lift_id _
id                       └┘                   └──┘  
src                      └┘                   └──┘  
typ                      └┘                   └──┘  
doc                      └┘                   └──┘  
1298  
1299  @[simp] theorem lift_univ : lift.{_ w} univ.{u v} = univ.{u (max v w)} := lift_lift _
doc    └──┘
1300  
1301  theorem univ_umax : univ.{u (max (u+1) v)} = univ.{u v} := congr_fun lift_umax _
1302  
1303  def lift.principal_seg : @principal_seg ordinal.{u} ordinal.{max (u+1) v} (<) (<) :=
id                                           └──┘  
src                                          └──┘  
typ                                          └──┘  
doc                                          └──┘  
1304  ⟨↑lift.initial_seg.{u (max (u+1) v)}, univ.{u v}, begin
1305    refine λ b, induction_on b _, introsI β s _,
1306    rw [univ, ← lift_umax], split; intro h,
1307    { rw ← lift_id (type s) at h ⊢,
1308      cases lift_type_lt.1 h with f, cases f with f a hf,
1309      existsi a, revert hf,
id               
typ              
1310      apply induction_on a, intros α r _ hf,
id                          
typ                         
1311      refine lift_type_eq.{u (max (u+1) v) (max (u+1) v)}.2
1312        ⟨(order_iso.of_surjective (order_embedding.of_monotone _ _) _).symm⟩,
1313      { exact λ b, enum r (f b) ((hf _).2 ⟨_, rfl⟩) },
id                        
typ                       
st                                                     └┘
1314      { refine λ a b h, (typein_lt_typein r).1 _,
id                                        
typ                                       
1315        rw [typein_enum, typein_enum],
1316        exact f.ord'.1 h },
id                        
typ                       
st                          └┘
1317      { intro a', cases (hf _).1 (typein_lt_type _ a') with b e,
id                                                    └┘
typ                                                   └┘
1318        existsi b, simp, simp [e] } },
id                 
typ                
st                                   └──┘
1319    { cases h with a e, rw [← e],
1320      apply induction_on a, intros α r _,
id                          
typ                         
1321      exact lift_type_lt.{u (u+1) (max (u+1) v)}.2
1322        ⟨typein.principal_seg r⟩ }
id                               
typ                              
st                                  └─
1323  end⟩
st   ──┘
1324  
1325  @[simp] theorem lift.principal_seg_coe :
doc    └──┘
1326    (lift.principal_seg.{u v} : ordinal → ordinal) = lift.{u (max (u+1) v)} := rfl
id                                 └┘  └┘
src                                └┘  └┘
typ                                └┘  └┘
doc                                └┘  └┘
1327  
1328  @[simp] theorem lift.principal_seg_top : lift.principal_seg.top = univ := rfl
doc    └──┘
1329  
1330  theorem lift.principal_seg_top' :
1331    lift.principal_seg.{u (u+1)}.top = @type ordinal.{u} (<) _ :=
id                                              └──┘  
src                                             └──┘  
typ                                             └──┘  
doc                                             └──┘  
1332  by simp only [lift.principal_seg_top, univ_id]
1333  
1334  /-- `a - b` is the unique ordinal satisfying
1335    `b + (a - b) = a` when `b ≤ a`. -/
1336  def sub (a b : ordinal.{u}) : ordinal.{u} :=
id                  └┘  └┘          └──┘
src                 └┘  └┘          └──┘
typ                 └┘  └┘          └──┘
doc                 └┘  └┘          └──┘
1337  omin {o | a ≤ b+o} ⟨a, le_add_left _ _⟩
id                   
typ                  
1338  
1339  instance : has_sub ordinal := ⟨sub⟩
id                      └──┘  
src                     └──┘  
typ                     └──┘  
doc                     └──┘  
1340  
1341  theorem le_add_sub (a b : ordinal) : a ≤ b + (a - b) :=
id                             └┘  └┘               
src                            └┘  └┘
typ                            └┘  └┘               
doc                            └┘  └┘
1342  omin_mem {o | a ≤ b+o} _
id                    
typ                   
1343  
1344  theorem sub_le {a b c : ordinal} : a - b ≤ c ↔ a ≤ b + c :=
id                             └┘                    
src                            └┘                
typ                            └┘                    
doc                            └┘
1345  ⟨λ h, le_trans (le_add_sub a b) (add_le_add_left h _),
id                               
typ                              
1346   λ h, omin_le h⟩
1347  
1348  theorem lt_sub {a b c : ordinal} : a < b - c ↔ c + a < b :=
id                             └┘                    
src                            └┘                
typ                            └┘                    
doc                            └┘  
1349  lt_iff_lt_of_le_iff_le sub_le
1350  
1351  theorem add_sub_cancel (a b : ordinal) : a + b - a = b :=
id                                  └┘  └┘             
src                                 └┘  └┘
typ                                 └┘  └┘             
doc                                 └┘  └┘
1352  le_antisymm (sub_le.2 $ le_refl _)
1353    ((add_le_add_iff_left a).1 $ le_add_sub _ _)
id                           
typ                          
1354  
1355  theorem sub_eq_of_add_eq {a b c : ordinal} (h : a + b = c) : c - a = b :=
id                                       └┘                          
src                                      └┘  
typ                                      └┘                          
doc                                      └┘  
1356  h ▸ add_sub_cancel _ _
1357  
1358  theorem sub_le_self (a b : ordinal) : a - b ≤ a :=
id                                └┘            
src                               └┘  
typ                               └┘            
doc                               └┘  
1359  sub_le.2 $ le_add_left _ _
1360  
1361  theorem add_sub_cancel_of_le {a b : ordinal} (h : b ≤ a) : b + (a - b) = a :=
id                                       └┘  └┘                           
src                                      └┘  └┘
typ                                      └┘  └┘                           
doc                                      └┘  └┘
1362  le_antisymm begin
1363    rcases zero_or_succ_or_limit (a-b) with e|⟨c,e⟩|l,
id                                    
typ                                   
1364    { simp only [e, add_zero, h] },
st                                  └┘
1365    { rw [e, add_succ, succ_le, ← lt_sub, e], apply lt_succ_self },
st                                                                  └┘
1366    { exact (add_le_of_limit l).2 (λ c l, le_of_lt (lt_sub.1 l)) }
id                                      
typ                                     
st                                                                  └─
1367  end (le_add_sub _ _)
st   ──┘
1368  
1369  @[simp] theorem sub_zero (a : ordinal) : a - 0 = a :=
id                                 └──┘             
src                                └──┘  
typ                                └──┘             
doc    └──┘                        └──┘  
1370  by simpa only [zero_add] using add_sub_cancel 0 a
id                                                   
typ                                                  
1371  
1372  @[simp] theorem zero_sub (a : ordinal) : 0 - a = 0 :=
id                                 └──┘          
src                                └──┘  
typ                                └──┘          
doc    └──┘                        └──┘  
1373  by rw ← le_zero; apply sub_le_self
1374  
1375  @[simp] theorem sub_self (a : ordinal) : a - a = 0 :=
id                                 └──┘         
src                                └──┘  
typ                                └──┘         
doc    └──┘                        └──┘  
1376  by simpa only [add_zero] using add_sub_cancel a 0
id                                                 
typ                                                
1377  
1378  theorem sub_eq_zero_iff_le {a b : ordinal} : a - b = 0 ↔ a ≤ b :=
id                                     └┘  └┘                 
src                                    └┘  └┘               
typ                                    └┘  └┘                 
doc                                    └┘  └┘
1379  ⟨λ h, by simpa only [h, add_zero] using le_add_sub a b,
id                                                       
typ                                                      
1380   λ h, by rwa [← le_zero, sub_le, add_zero]⟩
1381  
1382  theorem sub_sub (a b c : ordinal) : a - b - c = a - (b + c) :=
id                            └┘  └┘                      
src                           └┘  └┘
typ                           └┘  └┘                      
doc                           └┘  └┘
1383  eq_of_forall_ge_iff $ λ d, by rw [sub_le, sub_le, sub_le, add_assoc]
id                           
typ                          
st                                                                      
1384  
1385  theorem add_sub_add_cancel (a b c : ordinal) : a + b - (a + c) = b - c :=
id                                       └┘  └┘                       
src                                      └┘  └┘
typ                                      └┘  └┘                       
doc                                      └┘  └┘
1386  by rw [← sub_sub, add_sub_cancel]
1387  
1388  theorem sub_is_limit {a b} (l : is_limit a) (h : b < a) : is_limit (a - b) :=
id                                   └┘  └┘                 └┘  └┘       
src                                  └┘  └┘                    └┘  └┘
typ                                  └┘  └┘                 └┘  └┘       
doc                                  └┘  └┘                    └┘  └┘
1389  ⟨ne_of_gt $ lt_sub.2 $ by rwa add_zero,
1390   λ c h, by rw [lt_sub, add_succ]; exact l.2 _ (lt_sub.1 h)⟩
id                                          
typ                                         
1391  
1392  @[simp] theorem one_add_omega : 1 + omega.{u} = omega :=
id                                       └───┘       └─┘ 
src                                      └───┘       └─┘ 
typ                                      └───┘       └─┘ 
doc    └──┘                              └───┘       └─┘ 
1393  begin
1394    refine le_antisymm _ (le_add_left _ _),
1395    rw [omega, one_eq_lift_type_unit, ← lift_add, lift_le, type_add],
1396    have : is_well_order unit empty_relation := by apply_instance,
id                          └──┘                       └───────────┘
src                         └──┘                       └───────────┘
typ                         └──┘                       └───────────┘
doc                         └──┘                       └───────────┘
st                                                     └───────────┘
1397    refine ⟨order_embedding.collapse (order_embedding.of_monotone _ _)⟩,
1398    { apply sum.rec, exact λ _, 0, exact nat.succ },
id                                         └──────┘
src                                         └──────┘
typ                                        └──────┘
st                                                   └┘
1399    { intros a b, cases a; cases b; intro H; cases H with _ _ H _ _ H;
id                         
typ                        
1400      [cases H, exact nat.succ_pos _, exact nat.succ_lt_succ H] }
id                                                             
typ                                                            
st                                                                 └─
1401  end
st   ──┘
1402  
1403  @[simp] theorem one_add_of_omega_le {o} (h : omega ≤ o) : 1 + o = o :=
id                                                └───┘              
src                                               └───┘
typ                                               └───┘              
doc    └──┘                                       └───┘
1404  by rw [← add_sub_cancel_of_le h, ← add_assoc, one_add_omega]
st                                                              
1405  
1406  instance : monoid ordinal.{u} :=
id                     └──┘  
src                    └──┘  
typ                    └──┘  
doc                    └──┘  
1407  { mul := λ a b, quotient.lift_on₂ a b
id                                    
typ                                   
1408        (λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, ⟦⟨β × α, prod.lex s r, by exactI prod.lex.is_well_order⟩⟧
id                        
typ                       
1409          : Well_order → Well_order → ordinal) $
id             └────────┘   └────────┘   └─────┘
src            └────────┘   └────────┘   └─────┘
typ            └────────┘   └────────┘   └─────┘
doc                                      └─────┘
1410      λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
id                                                                 
typ                                                                
1411      quot.sound ⟨order_iso.prod_lex_congr g f⟩,
1412    one := 1,
1413    mul_assoc := λ a b c, quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩,
id                                                 
typ                                                
1414      eq.symm $ quotient.sound ⟨⟨prod_assoc _ _ _, λ a b, begin
1415        rcases a with ⟨⟨a₁, a₂⟩, a₃⟩,
1416        rcases b with ⟨⟨b₁, b₂⟩, b₃⟩,
1417        simp [prod.lex_def, and_or_distrib_left, or_assoc, and_assoc]
1418      end⟩⟩,
st       └─┘
1419    mul_one := λ a, induction_on a $ λ α r _, quotient.sound
id                                        
typ                                       
1420      ⟨⟨punit_prod _, λ a b, by rcases a with ⟨⟨⟨⟩⟩, a⟩; rcases b with ⟨⟨⟨⟩⟩, b⟩;
id                                                              
typ                                                             
1421      simp only [prod.lex_def, empty_relation, false_or]; dsimp only;
1422      simp only [eq_self_iff_true, true_and]; refl⟩⟩,
id                                               └──┘
src                                              └──┘
typ                                              └──┘
doc                                              └──┘
1423    one_mul := λ a, induction_on a $ λ α r _, quotient.sound
id                                        
typ                                       
1424      ⟨⟨prod_punit _, λ a b, by rcases a with ⟨a, ⟨⟨⟩⟩⟩; rcases b with ⟨b, ⟨⟨⟩⟩⟩;
id                                                              
typ                                                             
1425      simp only [prod.lex_def, empty_relation, and_false, or_false]; refl⟩⟩ }
id                                                                      └──┘
src                                                                     └──┘
typ                                                                     └──┘
doc                                                                     └──┘
1426  
1427  @[simp] theorem type_mul {α β : Type u} (r : α → α → Prop) (s : β → β → Prop)
id                                                                    
typ                                                                   
doc    └──┘
1428    [is_well_order α r] [is_well_order β s] : type r * type s = type (prod.lex s r) := rfl
id                                                                          
typ                                                                         
1429  
1430  @[simp] theorem lift_mul (a b) : lift (a * b) = lift a * lift b :=
id                                                              
typ                                                             
doc     └┘
1431  quotient.induction_on₂ a b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩,
id                           
typ                          
1432  quotient.sound ⟨(order_iso.preimage equiv.ulift _).trans
1433   (order_iso.prod_lex_congr (order_iso.preimage equiv.ulift _)
1434     (order_iso.preimage equiv.ulift _)).symm⟩
1435  
1436  @[simp] theorem card_mul (a b) : card (a * b) = card a * card b :=
id                                                              
typ                                                             
doc    └──┘
1437  quotient.induction_on₂ a b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩,
id                                          
typ                                         
1438  mul_comm (mk β) (mk α)
id             └┘     └┘
src            └┘     └┘
typ            └┘     └┘
doc            └┘     └┘
1439  
1440  @[simp] theorem mul_zero (a : ordinal) : a * 0 = 0 :=
id                                 └──┘  
src                                └──┘  
typ                                └──┘  
doc    └──┘                        └──┘  
1441  induction_on a $ λ α _ _, by exactI
id                      
typ                     
1442  type_eq_zero_iff_empty.2 (λ ⟨⟨e, _⟩⟩, e.elim)
1443  
1444  @[simp] theorem zero_mul (a : ordinal) : 0 * a = 0 :=
id                                 └──┘  
src                                └──┘  
typ                                └──┘  
doc    └──┘                        └──┘  
1445  induction_on a $ λ α _ _, by exactI
id                      
typ                     
1446  type_eq_zero_iff_empty.2 (λ ⟨⟨_, e⟩⟩, e.elim)
1447  
1448  theorem mul_add (a b c : ordinal) : a * (b + c) = a * b + a * c :=
id                            └┘  └┘                          
src                           └┘  └┘
typ                           └┘  └┘                          
doc                           └┘  └┘
1449  quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩,
id                            
typ                           
1450  quotient.sound ⟨⟨sum_prod_distrib _ _ _, begin
1451    rintro ⟨a₁|a₁, a₂⟩ ⟨b₁|b₁, b₂⟩; simp only [prod.lex_def,
1452      sum.lex_inl_inl, sum.lex.sep, sum.lex_inr_inl, sum.lex_inr_inr,
1453      sum_prod_distrib_apply_left, sum_prod_distrib_apply_right];
1454    simp only [sum.inl.inj_iff, true_or, false_and, false_or]
1455  end⟩⟩
st   └─┘
1456  
1457  @[simp] theorem mul_add_one (a b : ordinal) : a * (b + 1) = a * b + a :=
id                                      └┘  └┘                       
src                                     └┘  └┘
typ                                     └┘  └┘                       
doc    └──┘                             └┘  └┘
1458  by simp only [mul_add, mul_one]
1459  
1460  @[simp] theorem mul_succ (a b : ordinal) : a * succ b = a * b + a := mul_add_one _ _
id                                   └┘  └┘                      
src                                  └┘  └┘
typ                                  └┘  └┘                      
doc    └──┘                          └┘  └┘
1461  
1462  theorem mul_le_mul_left {a b} (c : ordinal) : a ≤ b → c * a ≤ c * b :=
id                                      └┘  └─┘                   
src                                     └┘  └─┘
typ                                     └┘  └─┘                   
doc                                     └┘  └─┘
1463  quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨f⟩, begin
id                            
typ                           
1464    resetI,
1465    refine type_le'.2 ⟨order_embedding.of_monotone
1466      (λ a, (f a.1, a.2))
1467      (λ a b h, _)⟩, clear_,
1468    cases h with a₁ b₁ a₂ b₂ h' a b₁ b₂ h',
1469    { exact prod.lex.left _ _ _ (f.to_order_embedding.ord'.1 h') },
id                                                              └┘
typ                                                             └┘
st                                                                  └┘
1470    { exact prod.lex.right _ _ h' }
id                                └┘
typ                               └┘
st                                   └─
1471  end
st   ──┘
1472  
1473  theorem mul_le_mul_right {a b} (c : ordinal) : a ≤ b → a * c ≤ b * c :=
id                                       └──┘                     
src                                      └──┘  
typ                                      └──┘                     
doc                                      └──┘  
1474  quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨f⟩, begin
id                            
typ                           
1475    resetI,
1476    refine type_le'.2 ⟨order_embedding.of_monotone
1477      (λ a, (a.1, f a.2))
1478      (λ a b h, _)⟩,
1479    cases h with a₁ b₁ a₂ b₂ h' a b₁ b₂ h',
1480    { exact prod.lex.left _ _ _ h' },
id                                 └┘
typ                                └┘
st                                    └┘
1481    { exact prod.lex.right _ _ (f.to_order_embedding.ord'.1 h') }
id                                                             └┘
typ                                                            └┘
st                                                                 └─
1482  end
st   ──┘
1483  
1484  theorem mul_le_mul {a b c d : ordinal} (h₁ : a ≤ c) (h₂ : b ≤ d) : a * b ≤ c * d :=
id                                                                           
typ                                                                          
1485  le_trans (mul_le_mul_left _ h₂) (mul_le_mul_right _ h₁)
1486  
1487  private lemma mul_le_of_limit_aux {α β r s} [is_well_order α r] [is_well_order β s]
id                                                                                 
typ                                                                                
1488    {c} (h : is_limit (type s)) (H : ∀ b' < type s, type r * b' ≤ c)
id               └┘  └┘                                      └┘   
src              └┘  └┘
typ              └┘  └┘                                      └┘   
doc              └┘  └┘
1489    (l : c < type r * type s) : false :=
id                              └┘ └┘
src                                └┘ └┘
typ                             └┘ └┘
1490  begin
1491    suffices : ∀ a b, prod.lex s r (b, a) (enum _ _ l),
id                               
typ                              
1492    { cases enum _ _ l with b a, exact irrefl _ (this _ _) },
st                                                            └┘
1493    intros a b,
1494    rw [← typein_lt_typein (prod.lex s r), typein_enum],
id                                       
typ                                      
1495    have := H _ (h.2 _ (typein_lt_type s b)),
id                                        
typ                                       
1496    rw [mul_succ] at this,
1497    have := lt_of_lt_of_le ((add_lt_add_iff_left _).2
1498      (typein_lt_type _ a)) this,
id                         
typ                        
1499    refine lt_of_le_of_lt _ this,
1500    refine (type_le'.2 _),
1501    constructor,
1502    refine order_embedding.of_monotone (λ a, _) (λ a b, _),
1503    { rcases a with ⟨⟨b', a'⟩, h⟩,
1504      by_cases e : b = b',
id                       └┘
typ                      └┘
1505      { refine sum.inr ⟨a', _⟩,
id                         └┘
typ                        └┘
1506        subst e, cases h with _ _ _ _ h _ _ _ h,
id               
typ              
1507        { exact (irrefl _ h).elim },
id                           
typ                          
st                                   └┘
1508        { exact h } },
id                 
typ                
st                   └──┘
1509      { refine sum.inl (⟨b', _⟩, a'),
id                          └┘      └┘
typ                         └┘      └┘
1510        cases h with _ _ _ _ h _ _ _ h,
1511        { exact h }, { exact (e rfl).elim } } },
id                              
typ                             
st                   └┘                      └────┘
1512    { rcases a with ⟨⟨b₁, a₁⟩, h₁⟩,
1513      rcases b with ⟨⟨b₂, a₂⟩, h₂⟩,
1514      intro h, by_cases e₁ : b = b₁; by_cases e₂ : b = b₂,
id                                 └┘                   └┘
typ                                └┘                   └┘
1515      { substs b₁ b₂, simpa only [subrel_val, prod.lex_def, @irrefl _ s _ b, true_and, false_or, eq_self_iff_true, dif_pos, sum.lex_inr_inr] using h },
id                                                                          
typ                                                                         
st                                                                                                                                                      └┘
1516      { subst b₁, simp only [subrel_val, prod.lex_def, e₂, prod.lex_def, dif_pos, subrel_val, eq_self_iff_true, or_false, dif_neg, not_false_iff, sum.lex_inr_inl, false_and] at h ⊢,
id               └┘                                       └┘                                                                          └───────────┘
src                                                                                                                                   └───────────┘
typ              └┘                                       └┘                                                                          └───────────┘
1517        cases h₂; [exact asymm h h₂_h, exact e₂ rfl] },
id                                 └──┘        └┘
typ                                └──┘        └┘
st                                                      └┘
1518      { simp only [e₂, dif_pos, eq_self_iff_true, dif_neg e₁, not_false_iff, sum.lex.sep] },
id                    └┘                                     └┘  └───────────┘
src                                                              └───────────┘
typ                   └┘                                     └┘  └───────────┘
st                                                                                           └┘
1519      { simpa only [dif_neg e₁, dif_neg e₂, prod.lex_def, subrel_val, subtype.mk_eq_mk, sum.lex_inl_inl] using h } }
id                             └┘          └┘
typ                            └┘          └┘
st                                                                                                                  └───
1520  end
st   ──┘
1521  
1522  theorem mul_le_of_limit {a b c : ordinal.{u}}
id                                    └┘  └┘
src                                   └┘  └┘
typ                                   └┘  └┘
doc                                   └┘  └┘
1523    (h : is_limit b) : a * b ≤ c ↔ ∀ b' < b, a * b' ≤ c :=
id            └┘                           └┘   
src           └┘                  
typ           └┘                           └┘   
doc           └┘  
1524  ⟨λ h b' l, le_trans (mul_le_mul_left _ (le_of_lt l)) h,
id        └┘
typ       └┘
1525  λ H, le_of_not_lt $ induction_on a (λ α r _, induction_on b $ λ β s _,
id                                                                
typ                                                               
1526    by exactI mul_le_of_limit_aux) h H⟩
id                                    
typ                                   
1527  
1528  theorem mul_is_normal {a : ordinal} (h : 0 < a) : is_normal ((*) a) :=
id                              └──┘                                
src                             └──┘  
typ                             └──┘                                
doc                             └──┘  
1529  ⟨λ b, by rw mul_succ; simpa only [add_zero] using (add_lt_add_iff_left (a*b)).2 h,
id                                                                           
typ                                                                          
1530   λ b l c, mul_le_of_limit l⟩
id                          
typ                         
1531  
1532  theorem lt_mul_of_limit {a b c : ordinal.{u}}
id                                    └┘  └┘
src                                   └┘  └┘
typ                                   └┘  └┘
doc                                   └┘  └┘
1533    (h : is_limit c) : a < b * c ↔ ∃ c' < c, a < b * c' :=
id            └┘                 └┘           └┘
src           └┘                  
typ           └┘                 └┘           └┘
doc           └┘  
1534  by simpa only [not_ball, not_le] using not_congr (@mul_le_of_limit b c a h)
id                                                                         
typ                                                                        
1535  
1536  theorem mul_lt_mul_iff_left {a b c : ordinal} (a0 : 0 < a) : a * b < a * c ↔ b < c :=
id                                        └┘  └┘                               
src                                       └┘  └┘                                
typ                                       └┘  └┘                               
doc                                       └┘  └┘
1537  (mul_is_normal a0).lt_iff
1538  
1539  theorem mul_le_mul_iff_left {a b c : ordinal} (a0 : 0 < a) : a * b ≤ a * c ↔ b ≤ c :=
id                                          └┘                                 
src                                         └┘                                 
typ                                         └┘                                 
doc                                         └┘  
1540  (mul_is_normal a0).le_iff
1541  
1542  theorem mul_lt_mul_of_pos_left {a b c : ordinal}
id                                             └┘  
src                                            └┘  
typ                                            └┘  
doc                                            └┘  
1543    (h : a < b) (c0 : 0 < c) : c * a < c * b :=
id                                       
typ                                      
1544  (mul_lt_mul_iff_left c0).2 h
1545  
1546  theorem mul_pos {a b : ordinal} (h₁ : 0 < a) (h₂ : 0 < b) : 0 < a * b :=
id                            └┘                                     
src                           └┘  
typ                           └┘                                     
doc                           └┘  
1547  by simpa only [mul_zero] using mul_lt_mul_of_pos_left h₂ h₁
1548  
1549  theorem mul_ne_zero {a b : ordinal} : a ≠ 0 → b ≠ 0 → a * b ≠ 0 :=
id                              └┘  └┘                      
src                             └┘  └┘
typ                             └┘  └┘                      
doc                             └┘  └┘
1550  by simpa only [pos_iff_ne_zero] using mul_pos
1551  
1552  theorem le_of_mul_le_mul_left {a b c : ordinal}
id                                          └┘  └┘
src                                         └┘  └┘
typ                                         └┘  └┘
doc                                         └┘  └┘
1553    (h : c * a ≤ c * b) (h0 : 0 < c) : a ≤ b :=
id                                      
typ                                     
1554  le_imp_le_of_lt_imp_lt (λ h', mul_lt_mul_of_pos_left h' h0) h
1555  
1556  theorem mul_left_inj {a b c : ordinal} (a0 : 0 < a) : a * b = a * c ↔ b = c :=
id                                   └┘                                
src                                  └┘                                 
typ                                  └┘                                
doc                                  └┘
1557  (mul_is_normal a0).inj
1558  
1559  theorem mul_is_limit {a b : ordinal}
id                                 └┘  
src                                └┘  
typ                                └┘  
doc                                └┘  
1560    (a0 : 0 < a) : is_limit b → is_limit (a * b) :=
id                               └┘  └┘       
src                                └┘  └┘
typ                              └┘  └┘       
doc                                └┘  └┘
1561  (mul_is_normal a0).is_limit
1562  
1563  theorem mul_is_limit_left {a b : ordinal}
id                                      └┘  
src                                     └┘  
typ                                     └┘  
doc                                     └┘  
1564    (l : is_limit a) (b0 : 0 < b) : is_limit (a * b) :=
id           └┘  └┘                  └┘  └┘       
src          └┘  └┘                    └┘  └┘
typ          └┘  └┘                  └┘  └┘       
doc          └┘  └┘                    └┘  └┘
1565  begin
1566    rcases zero_or_succ_or_limit b with rfl|⟨b,rfl⟩|lb,
id                                  
typ                                 
1567    { exact (lt_irrefl _).elim b0 },
st                                   └┘
1568    { rw mul_succ, exact add_is_limit _ l },
id                                         
typ                                        
st                                           └┘
1569    { exact mul_is_limit l.pos lb }
id                                └┘
typ                               └┘
st                                   └─
1570  end
st   ──┘
1571  
1572  /-- `a / b` is the unique ordinal `o` satisfying
1573    `a = b * o + o'` with `o' < b`. -/
1574  protected def div (a b : ordinal.{u}) : ordinal.{u} :=
id                            └┘  └┘          └──┘
src                           └┘  └┘          └──┘
typ                           └┘  └┘          └──┘
doc                           └┘  └┘          └──┘
1575  if h : b = 0 then 0 else
id          
typ         
1576  omin {o | a < b * succ o} ⟨a, succ_le.1 $
id                          
typ                         
1577    by simpa only [succ_zero, one_mul] using mul_le_mul_right (succ a) (succ_le.2 (pos_iff_ne_zero.2 h))⟩
id                                                                └──┘ 
src                                                               └──┘
typ                                                               └──┘ 
doc                                                               └──┘
1578  
1579  instance : has_div ordinal := ⟨ordinal.div⟩
id                      └──┘  
src                     └──┘  
typ                     └──┘  
doc                     └──┘  
1580  
1581  @[simp] theorem div_zero (a : ordinal) : a / 0 = 0 := dif_pos rfl
id                                 └──┘      
src                                └──┘  
typ                                └──┘      
doc    └──┘                        └──┘  
1582  
1583  -- TODO(lint): This should be a theorem but Lean fails to synthesize the placeholder
1584  @[nolint] def div_def (a) {b : ordinal} (h : b ≠ 0) :
id                                  └─────┘       
src                                 └─────┘
typ                                 └─────┘       
doc    └────┘                       └─────┘
1585    a / b = omin {o | a < b * succ o} _ := dif_neg h
id                               
typ                              
1586  
1587  theorem lt_mul_succ_div (a) {b : ordinal} (h : b ≠ 0) : a < b * succ (a / b) :=
id                                    └┘  └─┘                               
src                                   └┘  └─┘
typ                                   └┘  └─┘                               
doc                                   └┘  └─┘
1588  by rw div_def a h; exact omin_mem {o | a < b * succ o} _
id                                               └──┘
src                                                 └──┘
typ                                              └──┘
doc                                                 └──┘
1589  
1590  theorem lt_mul_div_add (a) {b : ordinal} (h : b ≠ 0) : a < b * (a / b) + b :=
id                                   └──┘                               
src                                  └──┘  
typ                                  └──┘                               
doc                                  └──┘  
1591  by simpa only [mul_succ] using lt_mul_succ_div a h
id                                                  
typ                                                 
1592  
1593  theorem div_le {a b c : ordinal} (b0 : b ≠ 0) : a / b ≤ c ↔ a < b * succ c :=
id                           └┘  └┘                                     
src                          └┘  └┘                            
typ                          └┘  └┘                                     
doc                          └┘  └┘
1594  ⟨λ h, lt_of_lt_of_le (lt_mul_succ_div a b0) (mul_le_mul_left _ $ succ_le_succ.2 h),
id                                         
typ                                        
1595   λ h, by rw div_def a b0; exact omin_le h⟩
1596  
1597  theorem lt_div {a b c : ordinal} (c0 : c ≠ 0) : a < b / c ↔ c * succ a ≤ b :=
id                           └┘  └┘                                     
src                          └┘  └┘                            
typ                          └┘  └┘                                     
doc                          └┘  └┘
1598  by rw [← not_le, div_le c0, not_lt]
st                                     
1599  
1600  theorem le_div {a b c : ordinal} (c0 : c ≠ 0) :
id                           └┘  └┘
src                          └┘  └┘
typ                          └┘  └┘
doc                          └┘  └┘
1601    a ≤ b / c ↔ c * a ≤ b :=
id                   
src              
typ                  
1602  begin
1603    apply limit_rec_on a,
1604    { simp only [mul_zero, zero_le] },
st                                     └┘
1605    { intros, rw [succ_le, lt_div c0] },
st                                      └┘
1606    { simp only [mul_le_of_limit, limit_le, iff_self, forall_true_iff] {contextual := tt} }
id                                                                                       └┘
src                                                                                      └┘
typ                                                                                      └┘
st                                                                                           └─
1607  end
st   ──┘
1608  
1609  theorem div_lt {a b c : ordinal} (b0 : b ≠ 0) :
id                           └┘  └┘
src                          └┘  └┘
typ                          └┘  └┘
doc                          └┘  └┘
1610    a / b < c ↔ a < b * c :=
id                   
src              
typ                  
1611  lt_iff_lt_of_le_iff_le $ le_div b0
1612  
1613  theorem div_le_of_le_mul {a b c : ordinal} (h : a ≤ b * c) : a / b ≤ c :=
id                                       └┘                          
src                                      └┘  
typ                                      └┘                          
doc                                      └┘  
1614  if b0 : b = 0 then by simp only [b0, div_zero, zero_le] else
id           
typ          
1615  (div_le b0).2 $ lt_of_le_of_lt h $
1616  mul_lt_mul_of_pos_left (lt_succ_self _) (pos_iff_ne_zero.2 b0)
1617  
1618  theorem mul_lt_of_lt_div {a b c : ordinal} : a < b / c → c * a < b :=
id                                     └┘  └┘                     
src                                    └┘  └┘
typ                                    └┘  └┘                     
doc                                    └┘  └┘
1619  lt_imp_lt_of_le_imp_le div_le_of_le_mul
1620  
1621  @[simp] theorem zero_div (a : ordinal) : 0 / a = 0 :=
id                                 └┘  └─┘        
src                                └┘  └─┘
typ                                └┘  └─┘        
doc    └──┘                        └┘  └─┘
1622  le_zero.1 $ div_le_of_le_mul $ zero_le _
1623  
1624  theorem mul_div_le (a b : ordinal) : b * (a / b) ≤ a :=
id                             └┘  └┘                
src                            └┘  └┘
typ                            └┘  └┘                
doc                            └┘  └┘
1625  if b0 : b = 0 then by simp only [b0, zero_mul, zero_le] else (le_div b0).1 (le_refl _)
id           
typ          
1626  
1627  theorem mul_add_div (a) {b : ordinal} (b0 : b ≠ 0) (c) : (b * a + c) / b = a + c / b :=
id                                └─────┘                                        
src                               └─────┘
typ                               └─────┘                                        
doc                               └─────┘
st                              └┘
1628  begin
1629    apply le_antisymm,
1630    { apply (div_le b0).2,
1631      rw [mul_succ, mul_add, add_assoc, add_lt_add_iff_left],
1632      apply lt_mul_div_add _ b0 },
st                                 └┘
1633    { rw [le_div b0, mul_add, add_le_add_iff_left],
1634      apply mul_div_le }
st                        └─
1635  end
st   ──┘
1636  
1637  theorem div_eq_zero_of_lt {a b : ordinal} (h : a < b) : a / b = 0 :=
id                                    └┘  └┘                  
src                                   └┘  └┘
typ                                   └┘  └┘                  
doc                                   └┘  └┘
1638  by rw [← le_zero, div_le $ pos_iff_ne_zero.1 $ lt_of_le_of_lt (zero_le _) h];
1639     simpa only [succ_zero, mul_one] using h
1640  
1641  @[simp] theorem mul_div_cancel (a) {b : ordinal} (b0 : b ≠ 0) : b * a / b = a :=
id                                           └──┘ └┘                         
src                                          └──┘ └┘
typ                                          └──┘ └┘                         
doc    └──┘                                  └──┘ └┘
1642  by simpa only [add_zero, zero_div] using mul_add_div a b0 0
id                                                        
typ                                                       
1643  
1644  @[simp] theorem div_one (a : ordinal) : a / 1 = a :=
id                                └──┘             
src                               └──┘  
typ                               └──┘             
doc    └──┘                       └──┘  
1645  by simpa only [one_mul] using mul_div_cancel a one_ne_zero
id                                                
typ                                               
1646  
1647  @[simp] theorem div_self {a : ordinal} (h : a ≠ 0) : a / a = 1 :=
id                                 └──┘                    
src                                └──┘  
typ                                └──┘                    
doc    └──┘                        └──┘  
1648  by simpa only [mul_one] using mul_div_cancel 1 h
1649  
1650  theorem mul_sub (a b c : ordinal) : a * (b - c) = a * b - a * c :=
id                            └┘  └┘                          
src                           └┘  └┘
typ                           └┘  └┘                          
doc                           └┘  └┘
1651  if a0 : a = 0 then by simp only [a0, zero_mul, sub_self] else
id           
typ          
1652  eq_of_forall_ge_iff $ λ d,
id                           
typ                          
1653  by rw [sub_le, ← le_div a0, sub_le, ← le_div a0, mul_add_div _ a0]
st                                                                    
1654  
1655  theorem is_limit_add_iff {a b} : is_limit (a + b) ↔ is_limit b ∨ (b = 0 ∧ is_limit a) :=
id                                    └┘  └┘           └┘  └┘             └┘  └┘ 
src                                   └┘  └┘             └┘  └┘               └┘  └┘
typ                                   └┘  └┘           └┘  └┘             └┘  └┘ 
doc                                   └┘  └┘              └┘  └┘                 └┘  └┘
1656  begin
1657    split; intro h,
1658    { by_cases h' : b = 0,
id                     
typ                    
1659      { rw [h', add_zero] at h, right, exact ⟨h', h⟩ },
id                                                   
typ                                                  
st                                                      └┘
1660        left, rw [←add_sub_cancel a b], apply sub_is_limit h,
id                                    
typ                                   
1661        suffices : a + 0 < a + b, simpa only [add_zero],
id                               
typ                              
1662        rwa [add_lt_add_iff_left, pos_iff_ne_zero] },
st                                                    └┘
1663    rcases h with h|⟨rfl, h⟩, exact add_is_limit a h, simpa only [add_zero]
id                                                   
typ                                                  
1664  end
st   └─┘
1665  
1666  /-- Divisibility is defined by right multiplication:
1667    `a ∣ b` if there exists `c` such that `b = a * c`. -/
1668  instance : has_dvd ordinal := ⟨λ a b, ∃ c, b = a * c⟩
id                      └──┘                      
src                     └──┘  
typ                     └──┘                      
doc                     └──┘  
1669  
1670  theorem dvd_def {a b : ordinal} : a ∣ b ↔ ∃ c, b = a * c := iff.rfl
id                            └┘                     
src                           └┘            
typ                           └┘                     
doc                           └┘  
1671  
1672  theorem dvd_mul (a b : ordinal) : a ∣ a * b := ⟨_, rfl⟩
id                            └┘            
src                           └┘
typ                           └┘            
doc                           └┘
1673  
1674  theorem dvd_trans : ∀ {a b c : ordinal}, a ∣ b → b ∣ c → a ∣ c
id                                                           
typ                                                          
1675  | a _ _ ⟨b, rfl⟩ ⟨c, rfl⟩ := ⟨b * c, mul_assoc _ _ _⟩
id                    
typ                   
1676  
1677  theorem dvd_mul_of_dvd {a b : ordinal} (c) (h : a ∣ b) : a ∣ b * c :=
id                                 └┘  └┘                         
src                                └┘  └┘
typ                                └┘  └┘                         
doc                                └┘  └┘
1678  dvd_trans h (dvd_mul _ _)
1679  
1680  theorem dvd_add_iff : ∀ {a b c : ordinal}, a ∣ b → (a ∣ b + c ↔ a ∣ c)
id                                                                 
typ                                                                
1681  | a _ c ⟨b, rfl⟩ :=
id            
typ           
1682   ⟨λ ⟨d, e⟩, ⟨d - b, by rw [mul_sub, ← e, add_sub_cancel]⟩,
id        
typ       
st                                                          
1683    λ ⟨d, e⟩, by rw [e, ← mul_add]; apply dvd_mul⟩
1684  
1685  theorem dvd_add {a b c : ordinal} (h₁ : a ∣ b) : a ∣ c → a ∣ b + c :=
id                            └┘  └┘                             
src                           └┘  └┘
typ                           └┘  └┘                             
doc                           └┘  └┘
1686  (dvd_add_iff h₁).2
1687  
1688  theorem dvd_zero (a : ordinal) : a ∣ 0 := ⟨_, (mul_zero _).symm⟩
id                           └──┘
src                          └──┘
typ                          └──┘
doc                          └──┘
1689  
1690  theorem zero_dvd {a : ordinal} : 0 ∣ a ↔ a = 0 :=
id                         └┘  └─┘          
src                        └┘  └─┘          
typ                        └┘  └─┘          
doc                        └┘  └─┘
1691  ⟨λ ⟨h, e⟩, by simp only [e, zero_mul], λ e, e.symm ▸ dvd_zero _⟩
1692  
1693  theorem one_dvd (a : ordinal) : 1 ∣ a := ⟨a, (one_mul _).symm⟩
id                        └──┘               
src                       └──┘  
typ                       └──┘               
doc                       └──┘  
1694  
1695  theorem div_mul_cancel : ∀ {a b : ordinal}, a ≠ 0 → a ∣ b → a * (b / a) = b
id                                                                       
typ                                                                      
1696  | a _ a0 ⟨b, rfl⟩ := by rw [mul_div_cancel _ a0]
st                                                  
1697  
1698  theorem le_of_dvd : ∀ {a b : ordinal}, b ≠ 0 → a ∣ b → a ≤ b
id                                                          
typ                                                         
1699  | a _ b0 ⟨b, rfl⟩ := by simpa only [mul_one] using mul_le_mul_left a
id                                                                      
typ                                                                     
1700    (one_le_iff_ne_zero.2 (λ h : b = 0, by simpa only [h, mul_zero] using b0))
id                                  
typ                                 
1701  
1702  theorem dvd_antisymm {a b : ordinal} (h₁ : a ∣ b) (h₂ : b ∣ a) : a = b :=
id                               └┘  └┘                              
src                              └┘  └┘
typ                              └┘  └┘                              
doc                              └┘  └┘
1703  if a0 : a = 0 then by subst a; exact (zero_dvd.1 h₁).symm else
id           
typ          
1704  if b0 : b = 0 then by subst b; exact zero_dvd.1 h₂ else
id                              
typ                             
1705  le_antisymm (le_of_dvd b0 h₁) (le_of_dvd a0 h₂)
1706  
1707  /-- `a % b` is the unique ordinal `o'` satisfying
1708    `a = b * o + o'` with `o' < b`. -/
1709  instance : has_mod ordinal := ⟨λ a b, a - b * (a / b)⟩
id                      └──┘                       
src                     └──┘  
typ                     └──┘                       
doc                     └──┘  
1710  
1711  theorem mod_def (a b : ordinal) : a % b = a - b * (a / b) := rfl
id                            └┘                      
src                           └┘  
typ                           └┘                      
doc                           └┘  
1712  
1713  @[simp] theorem mod_zero (a : ordinal) : a % 0 = a :=
id                                 └┘  └─┘           
src                                └┘  └─┘
typ                                └┘  └─┘           
doc    └──┘                        └┘  └─┘
1714  by simp only [mod_def, div_zero, zero_mul, sub_zero]
1715  
1716  theorem mod_eq_of_lt {a b : ordinal} (h : a < b) : a % b = a :=
id                               └┘  └┘                     
src                              └┘  └┘
typ                              └┘  └┘                     
doc                              └┘  └┘
1717  by simp only [mod_def, div_eq_zero_of_lt h, mul_zero, sub_zero]
1718  
1719  @[simp] theorem zero_mod (b : ordinal) : 0 % b = 0 :=
id                                 └──┘          
src                                └──┘  
typ                                └──┘          
doc    └──┘                        └──┘  
1720  by simp only [mod_def, zero_div, mul_zero, sub_self]
1721  
1722  theorem div_add_mod (a b : ordinal) : b * (a / b) + a % b = a :=
id                              └┘  └┘                      
src                             └┘  └┘
typ                             └┘  └┘                      
doc                             └┘  └┘
1723  add_sub_cancel_of_le $ mul_div_le _ _
1724  
1725  theorem mod_lt (a) {b : ordinal} (h : b ≠ 0) : a % b < b :=
id                           └┘  └─┘                      
src                          └┘  └─┘
typ                          └┘  └─┘                      
doc                          └┘  └─┘
1726  (add_lt_add_iff_left (b * (a / b))).1 $
id                                
typ                               
1727  by rw div_add_mod; exact lt_mul_div_add a h
id                                           
typ                                          
1728  
1729  @[simp] theorem mod_self (a : ordinal) : a % a = 0 :=
id                                 └──┘         
src                                └──┘  
typ                                └──┘         
doc    └──┘                        └──┘  
1730  if a0 : a = 0 then by simp only [a0, zero_mod] else
id           
typ          
1731  by simp only [mod_def, div_self a0, mul_one, sub_self]
1732  
1733  @[simp] theorem mod_one (a : ordinal) : a % 1 = 0 :=
id                                └──┘  
src                               └──┘  
typ                               └──┘  
doc    └──┘                       └──┘  
1734  by simp only [mod_def, div_one, one_mul, sub_self]
1735  
1736  end ordinal
1737  
1738  namespace cardinal
1739  open ordinal
1740  
1741  /-- The ordinal corresponding to a cardinal `c` is the least ordinal
1742    whose cardinal is `c`. -/
1743  def ord (c : cardinal) : ordinal :=
id                └┘  └──┘      └──┘
src               └┘  └──┘      └──┘
typ               └┘  └──┘      └──┘
doc               └┘  └──┘      └──┘
1744  begin
st    └──┘
1745    let ι := λ α, {r // is_well_order α r},
id                   
typ                  
st   └┘
1746    have : Π α, ι α := λ α, ⟨well_ordering_rel, by apply_instance⟩,
id                        
typ                       
1747    let F := λ α, ordinal.min ⟨this _⟩ (λ i:ι α, ⟦⟨α, i.1, i.2⟩⟧),
id                               └──┘         
typ                              └──┘         
1748    refine quot.lift_on c F _,
id                          
typ                         
1749    suffices : ∀ {α β}, α ≈ β → F α ≤ F β,
id                                     
typ                                    
1750    from λ α β h, le_antisymm (this h) (this (setoid.symm h)),
id             
typ            
1751    intros α β h, cases h with f, refine ordinal.le_min.2 (λ i, _),
id                                                              
typ                                                             
1752    haveI := @order_embedding.is_well_order _ _
1753      (f ⁻¹'o i.1) _ ↑(order_iso.preimage f i.1) i.2,
id                                                  
typ                                                 
1754    rw ← show type (f ⁻¹'o i.1) = ⟦⟨β, i.1, i.2⟩⟧, from
id                                     
typ                                    
1755      quot.sound ⟨order_iso.preimage f i.1⟩,
id                                        
typ                                       
1756    exact ordinal.min_le (λ i:ι α, ⟦⟨α, i.1, i.2⟩⟧) ⟨_, _⟩
id                                     
typ                                    
1757  end
st   └─┘
1758  
1759  -- TODO(lint): This should be a theorem but Lean fails to synthesize the placeholders
1760  @[nolint] def ord_eq_min (α : Type u) : ord (mk α) =
id                                                └┘ 
src                                               └┘
typ                                               └┘ 
doc    └────┘                                     └┘
1761    @ordinal.min _ _ (λ i:{r // is_well_order α r}, ⟦⟨α, i.1, i.2⟩⟧) := rfl
id                                                    
typ                                                   
1762  
1763  theorem ord_eq (α) : ∃ (r : α → α → Prop) [wo : is_well_order α r],
id                                                                
typ                                                               
1764    ord (mk α) = @type α r wo :=
id                          
typ                         
1765  let ⟨⟨r, wo⟩, h⟩ := @ordinal.min_eq {r // is_well_order α r}
id                                                           
typ                                                          
1766    ⟨⟨well_ordering_rel, by apply_instance⟩⟩
1767    (λ i:{r // is_well_order α r}, ⟦⟨α, i.1, i.2⟩⟧) in
id                                   
typ                                  
1768  ⟨r, wo, h⟩
1769  
1770  theorem ord_le_type (r : α → α → Prop) [is_well_order α r] : ord (mk α) ≤ ordinal.type r :=
id                                                                                     
typ                                                                                    
1771  @ordinal.min_le {r // is_well_order α r}
id                                       
typ                                      
1772    ⟨⟨well_ordering_rel, by apply_instance⟩⟩
1773    (λ i:{r // is_well_order α r}, ⟦⟨α, i.1, i.2⟩⟧) ⟨r, _⟩
id                                    
typ                                   
1774  
1775  theorem ord_le {c o} : ord c ≤ o ↔ c ≤ o.card :=
id                                       └┘  
src                                         └┘  
typ                                      └┘  
doc                                          └┘  
1776  quotient.induction_on c $ λ α, induction_on o $ λ β s _,
id                                                    
typ                                                   
1777  let ⟨r, _, e⟩ := ord_eq α in begin
id                           
typ                          
1778    resetI, simp only [mk_def, card_type], split; intro h,
1779    { rw e at h, exact let ⟨f⟩ := h in ⟨f.to_embedding⟩ },
id                             
typ                            
st                                                         └┘
1780    { cases h with f,
1781      have g := order_embedding.preimage f s,
id                                           
typ                                          
1782      haveI := order_embedding.is_well_order g,
1783      exact le_trans (ord_le_type _) (type_le'.2 ⟨g⟩) }
st                                                       └─
1784  end
st   ──┘
1785  
1786  theorem lt_ord {c o} : o < ord c ↔ o.card < c :=
id                                     └┘   
src                                       └┘
typ                                    └┘   
doc                                        └┘
1787  by rw [← not_le, ← not_le, ord_le]
st                                    
1788  
1789  @[simp] theorem card_ord (c) : (ord c).card = c :=
id                                        └┘      
src                                        └┘
typ                                       └┘      
doc    └──┘                                └┘
1790  quotient.induction_on c $ λ α,
id                              
typ                             
1791  let ⟨r, _, e⟩ := ord_eq α in by simp only [mk_def, e, card_type]
id                           
typ                          
1792  
1793  theorem ord_card_le (o : ordinal) : o.card.ord ≤ o :=
id                            └──┘      └┘       
src                           └──┘       └┘    
typ                           └──┘      └┘       
doc                           └──┘       └┘    
1794  ord_le.2 (le_refl _)
1795  
1796  lemma lt_ord_succ_card (o : ordinal) : o < o.card.succ.ord :=
id                               └┘  └─┘        └┘  └┘    
src                              └┘  └─┘          └┘  └┘    
typ                              └┘  └─┘        └┘  └┘    
doc                              └┘  └─┘          └┘  └┘    
1797  by { rw [lt_ord], apply cardinal.lt_succ_self }
st                                                 └┘
1798  
1799  @[simp] theorem ord_le_ord {c₁ c₂} : ord c₁ ≤ ord c₂ ↔ c₁ ≤ c₂ :=
id                                            └┘       └┘  └┘   
src                                                       
typ                                           └┘       └┘  └┘   
doc    └──┘
1800  by simp only [ord_le, card_ord]
1801  
1802  @[simp] theorem ord_lt_ord {c₁ c₂} : ord c₁ < ord c₂ ↔ c₁ < c₂ :=
id                                            └┘       └┘  └┘   
src                                                       
typ                                           └┘       └┘  └┘   
doc    └──┘
1803  by simp only [lt_ord, card_ord]
1804  
1805  @[simp] theorem ord_zero : ord 0 = 0 :=
doc    └──┘
1806  le_antisymm (ord_le.2 $ zero_le _) (ordinal.zero_le _)
1807  
1808  @[simp] theorem ord_nat (n : ℕ) : ord n = n :=
id                                           
src                               
typ                                          
doc    └──┘
1809  le_antisymm (ord_le.2 $ by simp only [card_nat]) $ begin
1810    induction n with n IH,
id               
typ              
1811    { apply ordinal.zero_le },
st                             └┘
1812    { exact (@ordinal.succ_le n _).2 (lt_of_le_of_lt IH $
1813      ord_lt_ord.2 $ nat_cast_lt.2 (nat.lt_succ_self n)) }
id                                                      
typ                                                     
st                                                          └─
1814  end
st   ──┘
1815  
1816  @[simp] theorem lift_ord (c) : (ord c).lift = ord (lift c) :=
id                                         └┘               
src                                         └┘
typ                                        └┘               
doc    └──┘                                 └┘
1817  eq_of_forall_ge_iff $ λ o, le_iff_le_iff_lt_iff_lt.2 $ begin
id                           
typ                          
1818    split; intro h,
1819    { rcases ordinal.lt_lift_iff.1 h with ⟨a, e, h⟩,
1820      rwa [← e, lt_ord, ← lift_card, lift_lt, ← lt_ord] },
st                                                         └┘
1821    { rw lt_ord at h,
1822      rcases lift_down' (le_of_lt h) with ⟨o, rfl⟩,
1823      rw [← lift_card, lift_lt] at h,
1824      rwa [ordinal.lift_lt, lt_ord] }
st                                     └─
1825  end
st   ──┘
1826  
1827  lemma mk_ord_out (c : cardinal) : mk c.ord.out.α = c :=
id                         └──┘  └┘       └┘      └┘   
src                        └──┘  └┘        └┘      └┘
typ                        └──┘  └┘       └┘      └┘   
doc                        └──┘  └┘        └┘
1828  by rw [←card_type c.ord.out.r, type_out, card_ord]
st                                                    
1829  
1830  lemma card_typein_lt (r : α → α → Prop) [is_well_order α r] (x : α)
id                                                         
typ                                                        
1831    (h : ord (mk α) = type r) : card (typein r x) < mk α :=
id                                                    
typ                                                   
1832  by { rw [←ord_lt_ord, h], refine lt_of_le_of_lt (ord_card_le _) (typein_lt_type r x) }
id                                                                                    
typ                                                                                   
st                                                                                        └┘
1833  
1834  lemma card_typein_out_lt (c : cardinal) (x : c.ord.out.α) : card (typein c.ord.out.r x) < c :=
id                                 └──┘  └┘             └┘                 └┘              
src                                └──┘  └┘              └┘                  └┘
typ                                └──┘  └┘             └┘                 └┘              
doc                                └──┘  └┘                                  └┘
1835  by { convert card_typein_lt c.ord.out.r x _, rw [mk_ord_out], rw [type_out, mk_ord_out] }
st                                                                                          └┘
1836  
1837  lemma ord_injective : injective ord :=
1838  by { intros c c' h, rw [←card_ord c, ←card_ord c', h] }
id                                                 └┘
typ                                                └┘
st                                                        └┘
1839  
1840  def ord.order_embedding : @order_embedding cardinal ordinal (<) (<) :=
id                                              └──┘  └┘ └┘  └─┘
src                                             └──┘  └┘ └┘  └─┘
typ                                             └──┘  └┘ └┘  └─┘
doc                                             └──┘  └┘ └┘  └─┘
1841  order_embedding.of_monotone cardinal.ord $ λ a b, cardinal.ord_lt_ord.2
id                                                 
typ                                                
1842  
1843  @[simp] theorem ord.order_embedding_coe :
doc    └──┘
1844    (ord.order_embedding : cardinal → ordinal) = ord := rfl
id                            └┘  └┘     └──┘  
src                           └┘  └┘     └──┘  
typ                           └┘  └┘     └──┘  
doc                           └┘  └┘     └──┘  
1845  
1846  /-- The cardinal `univ` is the cardinality of ordinal `univ`, or
1847    equivalently the cardinal of `ordinal.{u}`, or `cardinal.{u}`,
1848    as an element of `cardinal.{v}` (when `u < v`). -/
1849  def univ := lift.{(u+1) v} (mk ordinal)
id                                  └──┘  
src                                 └──┘  
typ                                 └──┘  
doc                                 └──┘  
1850  
1851  theorem univ_id : univ.{u (u+1)} = mk ordinal := lift_id _
id                      └┘                 └──┘  
src                     └┘                 └──┘  
typ                     └┘                 └──┘  
doc                     └┘                 └──┘  
1852  
1853  @[simp] theorem lift_univ : lift.{_ w} univ.{u v} = univ.{u (max v w)} := lift_lift _
doc    └──┘
1854  
1855  theorem univ_umax : univ.{u (max (u+1) v)} = univ.{u v} := congr_fun lift_umax _
1856  
1857  theorem lift_lt_univ (c : cardinal) : lift.{u (u+1)} c < univ.{u (u+1)} :=
id                             └┘  └──┘                      └┘
src                            └┘  └──┘                       └┘
typ                            └┘  └──┘                      └┘
doc                            └┘  └──┘                       └┘
1858  by simpa only [lift.principal_seg_coe, lift_ord, lift_succ, ord_le, succ_le] using le_of_lt
1859    (lift.principal_seg.{u (u+1)}.lt_top (succ c).ord)
id                                           └──┘  └─┘
src                                          └──┘   └─┘
typ                                          └──┘  └─┘
doc                                          └──┘   └─┘
1860  
1861  theorem lift_lt_univ' (c : cardinal) : lift.{u (max (u+1) v)} c < univ.{u v} :=
id                              └──┘  └┘                           
src                             └──┘  └┘
typ                             └──┘  └┘                           
doc                             └──┘  └┘
1862  by simpa only [lift_lift, lift_univ, univ_umax] using
1863    lift_lt.{_ (max (u+1) v)}.2 (lift_lt_univ c)
id                                               
typ                                              
1864  
1865  @[simp] theorem ord_univ : ord univ.{u v} = ordinal.univ.{u v} :=
doc    └──┘
1866  le_antisymm (ord_card_le _) $ le_of_forall_lt $ λ o h,
id                                                     
typ                                                    
1867  lt_ord.2 begin
1868    rcases lift.principal_seg.{u v}.down'.1
1869      (by simpa only [lift.principal_seg_coe] using h) with ⟨o', rfl⟩,
1870    simp only [lift.principal_seg_coe], rw [← lift_card],
1871    apply lift_lt_univ'
1872  end
st   └─┘
1873  
1874  theorem lt_univ {c} : c < univ.{u (u+1)} ↔ ∃ c', c = lift.{u (u+1)} c' :=
id                            └┘                └┘                    └┘
src                            └┘             
typ                           └┘                └┘                    └┘
doc                            └┘
1875  ⟨λ h, begin
1876    have := ord_lt_ord.2 h,
1877    rw ord_univ at this,
1878    cases lift.principal_seg.{u (u+1)}.down'.1
1879      (by simpa only [lift.principal_seg_top]) with o e,
1880    have := card_ord c,
id                      
typ                     
1881    rw [← e, lift.principal_seg_coe, ← lift_card] at this,
1882    exact ⟨_, this.symm⟩
1883  end, λ ⟨c', e⟩, e.symm ▸ lift_lt_univ _⟩
st   └─┘
1884  
1885  theorem lt_univ' {c} : c < univ.{u v} ↔ ∃ c', c = lift.{u (max (u+1) v)} c' :=
id                                           └┘                            └┘
src                                        
typ                                          └┘                            └┘
1886  ⟨λ h, let ⟨a, e, h'⟩ := lt_lift_iff.1 h in begin
1887    rw [← univ_id] at h',
1888    rcases lt_univ.{u}.1 h' with ⟨c', rfl⟩,
1889    exact ⟨c', by simp only [e.symm, lift_lift]⟩
id            └┘
typ           └┘
1890  end, λ ⟨c', e⟩, e.symm ▸ lift_lt_univ' _⟩
st   └─┘
1891  
1892  end cardinal
1893  
1894  namespace ordinal
1895  
1896  @[simp] theorem card_univ : card univ = cardinal.univ := rfl
doc    └──┘
1897  
1898  /-- The supremum of a family of ordinals -/
1899  def sup {ι} (f : ι → ordinal) : ordinal :=
id                         └┘        └┘
src                         └┘        └┘
typ                        └┘        └┘
doc                         └┘        └┘
1900  omin {c | ∀ i, f i ≤ c}
id                     
typ                    
1901    ⟨(sup (cardinal.succ ∘ card ∘ f)).ord, λ i, le_of_lt $
id                                             
typ                                            
1902      cardinal.lt_ord.2 (lt_of_lt_of_le (cardinal.lt_succ_self _) (le_sup _ _))⟩
1903  
1904  theorem le_sup {ι} (f : ι → ordinal) : ∀ i, f i ≤ sup f :=
id                               └┘  └┘                
src                               └┘  └┘
typ                              └┘  └┘                
doc                               └┘  └┘
1905  omin_mem {c | ∀ i, f i ≤ c} _
id                         
typ                        
1906  
1907  theorem sup_le {ι} {f : ι → ordinal} {a} : sup f ≤ a ↔ ∀ i, f i ≤ a :=
id                                └┘                             
src                                └┘  
typ                               └┘                             
doc                                └┘  
1908  ⟨λ h i, le_trans (le_sup _ _) h, λ h, omin_le h⟩
id        
typ       
1909  
1910  theorem lt_sup {ι} {f : ι → ordinal} {a} : a < sup f ↔ ∃ i, a < f i :=
id                                └┘                            
src                                └┘
typ                               └┘                            
doc                                └┘
1911  by simpa only [not_forall, not_le] using not_congr (@sup_le _ f a)
id                                                                  
typ                                                                 
1912  
1913  theorem is_normal.sup {f} (H : is_normal f)
1914    {ι} {g : ι → ordinal} (h : nonempty ι) : f (sup g) = sup (f ∘ g) :=
id                  └┘  └┘         └┘  └┘                          
src                  └┘  └┘         └┘  └┘
typ                 └┘  └┘         └┘  └┘                          
doc                  └┘  └┘
1915  eq_of_forall_ge_iff $ λ a,
id                           
typ                          
1916  by rw [sup_le, comp, H.le_set' (λ_:ι, true) g (let ⟨i⟩ := h in ⟨i, ⟨⟩⟩)];
id                                        └──┘                      
src                                        └──┘                         
typ                                       └──┘                      
1917    intros; simp only [sup_le, true_implies_iff]
1918  
1919  theorem sup_ord {ι} (f : ι → cardinal) : sup (λ i, (f i).ord) = (cardinal.sup f).ord :=
id                                └┘  └┘                                       
src                                └┘  └┘
typ                               └┘  └┘                                       
doc                                └┘  └┘
1920  eq_of_forall_ge_iff $ λ a, by simp only [sup_le, cardinal.ord_le, cardinal.sup_le]
id                           
typ                          
1921  
1922  lemma sup_succ {ι} (f : ι → ordinal) : sup (λ i, succ (f i)) ≤ succ (sup f) :=
id                               └┘  └┘                                   
src                               └┘  └┘
typ                              └┘  └┘                                   
doc                               └┘  └┘
1923  by { rw [ordinal.sup_le], intro i, rw ordinal.succ_le_succ, apply ordinal.le_sup }
st                                                                                    └┘
1924  
1925  lemma unbounded_range_of_sup_ge {α β : Type u} (r : α → α → Prop) [is_well_order α r] (f : β → α)
id                                                                                             
typ                                                                                            
1926    (h : sup.{u u} (typein r ∘ f) ≥ type r) : unbounded r (range f) :=
id                                                              
typ                                                             
1927  begin
1928    apply (not_bounded_iff _).mp, rintro ⟨x, hx⟩, apply not_lt_of_ge h,
1929    refine lt_of_le_of_lt _ (typein_lt_type r x), rw [sup_le], intro y,
id                                              
typ                                             
1930    apply le_of_lt, rw typein_lt_typein, apply hx, apply mem_range_self
1931  end
st   └─┘
1932  
1933  /-- The supremum of a family of ordinals indexed by the set
1934    of ordinals less than some `o : ordinal.{u}`.
1935    (This is not a special case of `sup` over the subtype,
1936    because `{a // a < o} : Type (u+1)` and `sup` only works over
1937    families in `Type u`.) -/
1938  def bsup (o : ordinal.{u}) : (Π a < o, ordinal.{max u v}) → ordinal.{max u v} :=
id                   └──┘                    └┘                  └──┘
src                  └──┘                     └┘                  └──┘
typ                  └──┘                    └┘                  └──┘
doc                  └──┘                     └┘                  └──┘
1939  match o, o.out, o.out_eq with
id                  
typ                 
1940  | _, ⟨α, r, _⟩, rfl, f := by exactI sup (λ a, f (typein r a) (typein_lt_type _ _))
1941  end
1942  
1943  theorem bsup_le {o f a} : bsup.{u v} o f ≤ a ↔ ∀ i h, f i h ≤ a :=
id                                                              
typ                                                             
1944  match o, o.out, o.out_eq, f :
id                 
typ                
1945   ∀ o w (e : ⟦w⟧ = o) (f : Π (a : ordinal.{u}), a < o → ordinal.{(max u v)}),
id                                  └─┘  └┘               └──┘
src                                   └─┘  └┘                 └──┘
typ                                 └─┘  └┘               └──┘
doc                                   └─┘  └┘                 └──┘
1946     bsup._match_1 o w e f ≤ a ↔ ∀ i h, f i h ≤ a with
id                                            
typ                                           
1947  | _, ⟨α, r, _⟩, rfl, f := by rw [bsup._match_1, sup_le]; exactI
1948    ⟨λ H i h, by simpa only [typein_enum] using H (enum r i h), λ H b, H _ _⟩
id                                                                  
typ                                                                 
1949  end
1950  
1951  theorem bsup_type (r : α → α → Prop) [is_well_order α r] (f) :
id                                                       
typ                                                      
1952    bsup (type r) f = sup (λ a, f (typein r a) (typein_lt_type _ _)) :=
id                                          
typ                                         
1953  eq_of_forall_ge_iff $ λ o,
1954  by rw [bsup_le, sup_le]; exact
1955    ⟨λ H b, H _ _, λ H i h, by simpa only [typein_enum] using H (enum r i h)⟩
id                                                                      
typ                                                                     
1956  
1957  theorem le_bsup {o} (f : Π a < o, ordinal) (i h) : f i h ≤ bsup o f :=
id                                      └┘                        
src                                      └┘
typ                                     └┘                        
doc                                      └┘
1958  bsup_le.1 (le_refl _) _ _
1959  
1960  theorem lt_bsup {o : ordinal} {f : Π a < o, ordinal}
id                          └──┘                  └┘  
src                         └──┘                   └┘  
typ                         └──┘                  └┘  
doc                         └──┘                   └┘  
1961    (hf : ∀{a a'} (ha : a < o) (ha' : a' < o), a < a' → f a ha < f a' ha')
id              └┘                    └┘         └┘             └┘
typ             └┘                    └┘         └┘             └┘
1962    (ho : o.is_limit) (i h) : f i h < bsup o f :=
id           └┘ └┘ └┘                       
src           └┘ └┘ └┘
typ          └┘ └┘ └┘                       
doc           └┘ └┘ └┘
1963  lt_of_lt_of_le (hf _ _ $ lt_succ_self i) (le_bsup f i.succ $ ho.2 _ h)
id                                                        └┘   
src                                                         └┘
typ                                                       └┘   
doc                                                         └┘
1964  
1965  theorem bsup_id {o} (ho : is_limit o) : bsup.{u u} o (λ x _, x) = o :=
id                             └┘  └┘                              
src                            └┘  └┘
typ                            └┘  └┘                              
doc                            └┘  └┘
1966  begin
1967    apply le_antisymm, rw [bsup_le], intro i, apply le_of_lt,
1968    rw [←not_lt], intro h, apply lt_irrefl (bsup.{u u} o (λ x _, x)),
id                                                            
typ                                                           
1969    apply lt_of_le_of_lt _ (lt_bsup _ ho _ h), refl, intros, assumption
id                                       └┘
typ                                      └┘
1970  end
st   └─┘
1971  
1972  theorem is_normal.bsup {f} (H : is_normal f)
1973    {o : ordinal} : ∀ (g : Π a < o, ordinal) (h : o ≠ 0),
id          └──┘                       └┘         
src         └──┘                        └┘
typ         └──┘                       └┘         
doc         └──┘                        └┘
1974    f (bsup o g) = bsup o (λ a h, f (g a h)) :=
id                                     
typ                                    
1975  induction_on o $ λ α r _ g h,
id                       
typ                      
1976  by resetI; rw [bsup_type,
1977       H.sup (type_ne_zero_iff_nonempty.1 h), bsup_type]
st                                                        
1978  
1979  theorem is_normal.bsup_eq {f} (H : is_normal f) {o : ordinal} (h : is_limit o) :
id                                                        └──┘         └┘  └┘   
src                                                        └──┘         └┘  └┘
typ                                                       └──┘         └┘  └┘   
doc                                                        └──┘         └┘  └┘
1980    bsup.{u} o (λx _, f x) = f o :=
id                           
typ                          
1981  by { rw [←is_normal.bsup.{u u} H (λ x _, x) h.1, bsup_id h] }
st                                                              └┘
1982  
1983  /-- The ordinal exponential, defined by transfinite recursion. -/
1984  def power (a b : ordinal) : ordinal :=
id                    └┘  └┘      └──┘
src                   └┘  └┘      └──┘
typ                   └┘  └┘      └──┘
doc                   └┘  └┘      └──┘
1985  if a = 0 then 1 - b else
id                    
typ                   
1986  limit_rec_on b 1 (λ _ IH, IH * a) (λ b _, bsup.{u u} b)
id                       └┘  └┘                      
typ                      └┘  └┘                      
1987  
1988  instance : has_pow ordinal ordinal := ⟨power⟩
id                      └──┘   └┘ └┘ 
src                     └──┘   └┘ └┘ 
typ                     └──┘   └┘ └┘ 
doc                     └──┘   └┘ └┘ 
1989  local infixr ^ := @pow ordinal ordinal ordinal.has_pow
id                          └─────┘  └┘ └─┘   └┘  └┘  └┘  
src                         └─────┘  └┘ └─┘   └┘  └┘  └┘  
typ                         └─────┘  └┘ └─┘   └┘  └┘  └┘  
doc                         └─────┘  └┘ └─┘
1990  
1991  theorem zero_power' (a : ordinal) : 0 ^ a = 1 - a :=
id                            └──┘                 
src                           └──┘  
typ                           └──┘                 
doc                           └──┘  
1992  by simp only [pow, power, if_pos rfl]
1993  
1994  @[simp] theorem zero_power {a : ordinal} (a0 : a ≠ 0) : 0 ^ a = 0 :=
id                                   └──┘                      
src                                  └──┘  
typ                                  └──┘                      
doc    └──┘                          └──┘  
1995  by rwa [zero_power', sub_eq_zero_iff_le, one_le_iff_ne_zero]
1996  
1997  @[simp] theorem power_zero (a : ordinal) : a ^ 0 = 1 :=
id                                   └──┘      
src                                  └──┘  
typ                                  └──┘      
doc    └──┘                          └──┘  
1998  by by_cases a = 0; [simp only [pow, power, if_pos h, sub_zero],
1999  simp only [pow, power, if_neg h, limit_rec_on_zero]]
2000  
2001  @[simp] theorem power_succ (a b : ordinal) : a ^ succ b = a ^ b * a :=
id                                     └┘  └┘                      
src                                    └┘  └┘
typ                                    └┘  └┘                      
doc    └──┘                            └┘  └┘
2002  if h : a = 0 then by subst a; simp only [zero_power (succ_ne_zero _), mul_zero]
id          
typ         
2003  else by simp only [pow, power, limit_rec_on_succ, if_neg h]
2004  
2005  theorem power_limit {a b : ordinal} (a0 : a ≠ 0) (h : is_limit b) :
id                              └┘  └┘                    └┘  └┘   
src                             └┘  └┘                     └┘  └┘
typ                             └┘  └┘                    └┘  └┘   
doc                             └┘  └┘                     └┘  └┘
2006    a ^ b = bsup.{u u} b (λ c _, a ^ c) :=
id                                 
typ                                
2007  by simp only [pow, power, if_neg a0]; rw limit_rec_on_limit _ _ _ _ h; refl
id                                                                         └──┘
src                                                                         └──┘
typ                                                                        └──┘
doc                                                                         └──┘
2008  
2009  theorem power_le_of_limit {a b c : ordinal} (a0 : a ≠ 0) (h : is_limit b) :
id                                      └┘  └┘                     └┘  └┘   
src                                     └┘  └┘                     └┘  └┘
typ                                     └┘  └┘                     └┘  └┘   
doc                                     └┘  └┘                     └┘  └┘
2010    a ^ b ≤ c ↔ ∀ b' < b, a ^ b' ≤ c :=
id                         └┘   
src              
typ                        └┘   
2011  by rw [power_limit a0 h, bsup_le]
st                                   
2012  
2013  theorem lt_power_of_limit {a b c : ordinal} (b0 : b ≠ 0) (h : is_limit c) :
id                                      └┘  └┘                     └┘  └┘   
src                                     └┘  └┘                     └┘  └┘
typ                                     └┘  └┘                     └┘  └┘   
doc                                     └┘  └┘                     └┘  └┘
2014    a < b ^ c ↔ ∃ c' < c, a < b ^ c' :=
id               └┘           
src              
typ              └┘           
2015  by rw [← not_iff_not, not_exists]; simp only [not_lt, power_le_of_limit b0 h, exists_prop, not_and]
id                                                                              
typ                                                                             
2016  
2017  @[simp] theorem power_one (a : ordinal) : a ^ 1 = a :=
id                                  └──┘             
src                                 └──┘  
typ                                 └──┘             
doc    └──┘                         └──┘  
2018  by rw [← succ_zero, power_succ]; simp only [power_zero, one_mul]
2019  
2020  @[simp] theorem one_power (a : ordinal) : 1 ^ a = 1 :=
id                                  └──┘          
src                                 └──┘  
typ                                 └──┘          
doc    └──┘                         └──┘  
2021  begin
2022    apply limit_rec_on a,
2023    { simp only [power_zero] },
st                              └┘
2024    { intros _ ih, simp only [power_succ, ih, mul_one] },
st                                                        └┘
2025    refine λ b l IH, eq_of_forall_ge_iff (λ c, _),
id                                           
typ                                          
2026    rw [power_le_of_limit one_ne_zero l],
id                                       
typ                                      
2027    exact ⟨λ H, by simpa only [power_zero] using H 0 l.pos,
2028           λ H b' h, by rwa IH _ h⟩,
id                └┘
typ               └┘
2029  end
st   └─┘
2030  
2031  theorem power_pos {a : ordinal} (b)
id                          └──┘  
src                         └──┘  
typ                         └──┘  
doc                         └──┘  
2032    (a0 : 0 < a) : 0 < a ^ b :=
id                          
typ                         
2033  begin
2034    have h0 : 0 < a ^ 0, {simp only [power_zero, zero_lt_one]},
id                   
typ                  
st                                                              └┘
2035    apply limit_rec_on b,
id                        
typ                       
2036    { exact h0 },
st                └┘
2037    { intros b IH, rw [power_succ],
2038      exact mul_pos IH a0 },
st                           └┘
2039    { exact λ b l _, (lt_power_of_limit (pos_iff_ne_zero.1 a0) l).2
id                
typ               
2040        ⟨0, l.pos, h0⟩ },
st                        └┘
2041  end
st   └─┘
2042  
2043  theorem power_ne_zero {a : ordinal} (b)
id                              └──┘  
src                             └──┘  
typ                             └──┘  
doc                             └──┘  
2044    (a0 : a ≠ 0) : a ^ b ≠ 0 :=
id                      
typ                     
2045  pos_iff_ne_zero.1 $ power_pos b $ pos_iff_ne_zero.2 a0
id                                 
typ                                
2046  
2047  theorem power_is_normal {a : ordinal} (h : 1 < a) : is_normal ((^) a) :=
id                                └┘  └─┘                              
src                               └┘  └─┘
typ                               └┘  └─┘                              
doc                               └┘  └─┘
2048  have a0 : 0 < a, from lt_trans zero_lt_one h,
id                 
typ                
2049  ⟨λ b, by simpa only [mul_one, power_succ] using
id      
typ     
2050    (mul_lt_mul_iff_left (power_pos b a0)).2 h,
id                                     
typ                                    
2051   λ b l c, power_le_of_limit (ne_of_gt a0) l⟩
id                                          
typ                                         
2052  
2053  theorem power_lt_power_iff_right {a b c : ordinal}
id                                             └┘ └┘
src                                            └┘ └┘
typ                                            └┘ └┘
doc                                            └┘ └┘
2054    (a1 : 1 < a) : a ^ b < a ^ c ↔ b < c :=
id                                 
src                                 
typ                                
2055  (power_is_normal a1).lt_iff
2056  
2057  theorem power_le_power_iff_right {a b c : ordinal}
id                                               └┘  
src                                              └┘  
typ                                              └┘  
doc                                              └┘  
2058    (a1 : 1 < a) : a ^ b ≤ a ^ c ↔ b ≤ c :=
id                                  
src                                 
typ                                 
2059  (power_is_normal a1).le_iff
2060  
2061  theorem power_right_inj {a b c : ordinal}
id                                      └┘  
src                                     └┘  
typ                                     └┘  
doc                                     └┘  
2062    (a1 : 1 < a) : a ^ b = a ^ c ↔ b = c :=
id                                  
src                                 
typ                                 
2063  (power_is_normal a1).inj
2064  
2065  theorem power_is_limit {a b : ordinal}
id                                   └┘  
src                                  └┘  
typ                                  └┘  
doc                                  └┘  
2066    (a1 : 1 < a) : is_limit b → is_limit (a ^ b) :=
id                               └┘  └┘       
src                                └┘  └┘
typ                              └┘  └┘       
doc                                └┘  └┘
2067  (power_is_normal a1).is_limit
2068  
2069  theorem power_is_limit_left {a b : ordinal}
id                                        └┘  
src                                       └┘  
typ                                       └┘  
doc                                       └┘  
2070    (l : is_limit a) (hb : b ≠ 0) : is_limit (a ^ b) :=
id           └┘  └┘                  └┘  └┘       
src          └┘  └┘                    └┘  └┘
typ          └┘  └┘                  └┘  └┘       
doc          └┘  └┘                    └┘  └┘
2071  begin
2072    rcases zero_or_succ_or_limit b with e|⟨b,rfl⟩|l',
id                                  
typ                                 
2073    { exact absurd e hb },
st                         └┘
2074    { rw power_succ,
2075      exact mul_is_limit (power_pos _ l.pos) l },
id                                              
typ                                             
st                                                └┘
2076    { exact power_is_limit l.one_lt l' }
id                                     └┘
typ                                    └┘
st                                        └─
2077  end
st   ──┘
2078  
2079  theorem power_le_power_right {a b c : ordinal}
id                                         └┘  └┘
src                                        └┘  └┘
typ                                        └┘  └┘
doc                                        └┘  └┘
2080    (h₁ : 0 < a) (h₂ : b ≤ c) : a ^ b ≤ a ^ c :=
id                                       
typ                                      
2081  begin
2082    cases lt_or_eq_of_le (one_le_iff_pos.2 h₁) with h₁ h₁,
2083    { exact (power_le_power_iff_right h₁).2 h₂ },
st                                                └┘
2084    { subst a, simp only [one_power] }
id             
typ            
st                                      └─
2085  end
st   ──┘
2086  
2087  theorem power_le_power_left {a b : ordinal} (c)
id                                      └┘  └┘
src                                     └┘  └┘
typ                                     └┘  └┘
doc                                     └┘  └┘
2088    (ab : a ≤ b) : a ^ c ≤ b ^ c :=
id                            
typ                           
2089  begin
2090    by_cases a0 : a = 0,
2091    { subst a, by_cases c0 : c = 0,
id                             
typ                            
2092      { subst c, simp only [power_zero] },
id               
typ              
st                                         └┘
2093      { simp only [zero_power c0, zero_le] } },
st                                            └──┘
2094    { apply limit_rec_on c,
id                          
typ                         
2095      { simp only [power_zero] },
st                                └┘
2096      { intros c IH, simpa only [power_succ] using mul_le_mul IH ab },
st                                                                     └┘
2097      { exact λ c l IH, (power_le_of_limit a0 l).2
id                  
typ                 
2098          (λ b' h, le_trans (IH _ h) (power_le_power_right
id              └┘
typ             └┘
2099            (lt_of_lt_of_le (pos_iff_ne_zero.2 a0) ab) (le_of_lt h))) } }
st                                                                       └───
2100  end
st   ──┘
2101  
2102  theorem le_power_self {a : ordinal} (b) (a1 : 1 < a) : b ≤ a ^ b :=
id                              └──┘                            
src                             └──┘  
typ                             └──┘                            
doc                             └──┘  
2103  (power_is_normal a1).le_self _
2104  
2105  theorem power_lt_power_left_of_succ {a b c : ordinal}
id                                                  └┘  
src                                                 └┘  
typ                                                 └┘  
doc                                                 └┘  
2106    (ab : a < b) : a ^ succ c < b ^ succ c :=
id                                      
typ                                     
2107  by rw [power_succ, power_succ]; exact
2108  lt_of_le_of_lt
2109    (mul_le_mul_right _ $ power_le_power_left _ $ le_of_lt ab)
2110    (mul_lt_mul_of_pos_left ab (power_pos _ (lt_of_le_of_lt (zero_le _) ab)))
2111  
2112  theorem power_add (a b c : ordinal) : a ^ (b + c) = a ^ b * a ^ c :=
id                              └┘  └┘                          
src                             └┘  └┘
typ                             └┘  └┘                          
doc                             └┘  └┘
2113  begin
2114    by_cases a0 : a = 0,
2115    { subst a,
id             
typ            
2116      by_cases c0 : c = 0, {simp only [c0, add_zero, power_zero, mul_one]},
id                     
typ                    
st                                                                          └┘
2117      have : b+c ≠ 0 := ne_of_gt (lt_of_lt_of_le
id               
typ              
2118        (pos_iff_ne_zero.2 c0) (le_add_left _ _)),
2119      simp only [zero_power c0, zero_power this, mul_zero] },
st                                                            └┘
2120    cases eq_or_lt_of_le (one_le_iff_ne_zero.2 a0) with a1 a1,
2121    { subst a1, simp only [one_power, mul_one] },
st                                                └┘
2122    apply limit_rec_on c,
id                        
typ                       
2123    { simp only [add_zero, power_zero, mul_one] },
st                                                 └┘
2124    { intros c IH,
2125      rw [add_succ, power_succ, IH, power_succ, mul_assoc] },
st                                                           └┘
2126    { intros c l IH,
2127      refine eq_of_forall_ge_iff (λ d, (((power_is_normal a1).trans
id                                     
typ                                    
2128        (add_is_normal b)).limit_le l).trans _),
id                                    
typ                                   
2129      simp only [IH] {contextual := tt},
id                                     └┘
src                                    └┘
typ                                    └┘
2130      exact (((mul_is_normal $ power_pos b (pos_iff_ne_zero.2 a0)).trans
id                                          
typ                                         
2131        (power_is_normal a1)).limit_le l).symm }
id                                        
typ                                       
st                                                └─
2132  end
st   ──┘
2133  
2134  theorem power_dvd_power (a) {b c : ordinal}
id                                      └┘  └┘
src                                     └┘  └┘
typ                                     └┘  └┘
doc                                     └┘  └┘
2135    (h : b ≤ c) : a ^ b ∣ a ^ c :=
id                          
typ                         
2136  by rw [← add_sub_cancel_of_le h, power_add]; apply dvd_mul
2137  
2138  theorem power_dvd_power_iff {a b c : ordinal}
id                                        └┘  └┘
src                                       └┘  └┘
typ                                       └┘  └┘
doc                                       └┘  └┘
2139    (a1 : 1 < a) : a ^ b ∣ a ^ c ↔ b ≤ c :=
id                                 
src                                 
typ                                
2140  ⟨λ h, le_of_not_lt $ λ hn,
2141    not_le_of_lt ((power_lt_power_iff_right a1).2 hn) $
2142     le_of_dvd (power_ne_zero _ $ one_le_iff_ne_zero.1 $ le_of_lt a1) h,
2143  power_dvd_power _⟩
2144  
2145  theorem power_mul (a b c : ordinal) : a ^ (b * c) = (a ^ b) ^ c :=
id                                └┘                         
src                               └┘
typ                               └┘                         
doc                               └┘
2146  begin
2147    by_cases b0 : b = 0, {simp only [b0, zero_mul, power_zero, one_power]},
st                                                                          └┘
2148    by_cases a0 : a = 0,
id                   
typ                  
2149    { subst a,
id             
typ            
2150      by_cases c0 : c = 0, {simp only [c0, mul_zero, power_zero]},
id                     
typ                    
st                                                                 └┘
2151      simp only [zero_power b0, zero_power c0, zero_power (mul_ne_zero b0 c0)] },
st                                                                                └┘
2152    cases eq_or_lt_of_le (one_le_iff_ne_zero.2 a0) with a1 a1,
2153    { subst a1, simp only [one_power] },
st                                       └┘
2154    apply limit_rec_on c,
id                        
typ                       
2155    { simp only [mul_zero, power_zero] },
st                                        └┘
2156    { intros c IH,
2157      rw [mul_succ, power_add, IH, power_succ] },
st                                               └┘
2158    { intros c l IH,
2159      refine eq_of_forall_ge_iff (λ d, (((power_is_normal a1).trans
id                                     
typ                                    
2160        (mul_is_normal (pos_iff_ne_zero.2 b0))).limit_le l).trans _),
id                                                          
typ                                                         
2161      simp only [IH] {contextual := tt},
id                                     └┘
src                                    └┘
typ                                    └┘
2162      exact (power_le_of_limit (power_ne_zero _ a0) l).symm }
id                                                     
typ                                                    
st                                                             └─
2163  end
st   ──┘
2164  
2165  /-- The ordinal logarithm is the solution `u` to the equation
2166    `x = b ^ u * v + w` where `v < b` and `w < b`. -/
2167  def log (b : ordinal) (x : ordinal) : ordinal :=
id                └┘  └─┘        └┘ └┘     └┘ └┘ 
src               └┘  └─┘        └┘ └┘     └┘ └┘ 
typ               └┘  └─┘        └┘ └┘     └┘ └┘ 
doc               └┘  └─┘        └┘ └┘     └┘ └┘ 
2168  if h : 1 < b then pred $
id              
typ             
2169    omin {o | x < b^o} ⟨succ x, succ_le.1 (le_power_self _ h)⟩
id                          
typ                         
2170  else 0
2171  
2172  @[simp] theorem log_not_one_lt {b : ordinal} (b1 : ¬ 1 < b) (x : ordinal) : log b x = 0 :=
id                                        └┘ └┘                       └──┘         
src                                       └┘ └┘                        └──┘
typ                                       └┘ └┘                       └──┘         
doc    └──┘                               └┘ └┘                        └──┘
2173  by simp only [log, dif_neg b1]
2174  
2175  theorem log_def {b : ordinal} (b1 : 1 < b) (x : ordinal) : log b x =
id                        └──┘                     └┘  └─┘         
src                       └──┘                      └┘  └─┘
typ                       └──┘                     └┘  └─┘         
doc                       └──┘                      └┘  └─┘
2176    pred (omin {o | x < b^o} (log._proof_1 b x b1)) :=
id                                         
typ                                        
2177  by simp only [log, dif_pos b1]
2178  
2179  @[simp] theorem log_zero (b : ordinal) : log b 0 = 0 :=
id                                 └──┘          
src                                └──┘  
typ                                └──┘          
doc    └──┘                        └──┘  
2180  if b1 : 1 < b then
id               
typ              
2181    by rw [log_def b1, ← le_zero, pred_le];
2182       apply omin_le; change 0<b^succ 0;
id                                 └──┘
src                                 └──┘
typ                                └──┘
doc                                 └──┘
2183       rw [succ_zero, power_one];
2184       exact lt_trans zero_lt_one b1
2185  else by simp only [log_not_one_lt b1]
2186  
2187  theorem succ_log_def {b x : ordinal} (b1 : 1 < b) (x0 : 0 < x) : succ (log b x) =
id                               └┘  └┘                                        
src                              └┘  └┘
typ                              └┘  └┘                                        
doc                              └┘  └┘
2188    omin {o | x < b^o} (log._proof_1 b x b1) :=
id                                    
typ                                   
2189  begin
2190    let t := omin {o | x < b^o} (log._proof_1 b x b1),
id                                               
typ                                              
2191    have : x < b ^ t := omin_mem {o | x < b^o} _,
id                                      
typ                                     
2192    rcases zero_or_succ_or_limit t with h|h|h,
id                                  
typ                                 
2193    { refine (not_lt_of_le (one_le_iff_pos.2 x0) _).elim,
2194      simpa only [h, power_zero] },
st                                  └┘
2195    { rw [show log b x = pred t, from log_def b1 x,
id                └─┘      └──┘                   
src               └─┘       └──┘
typ               └─┘      └──┘                   
doc               └─┘       └──┘
2196          succ_pred_iff_is_succ.2 h] },
st                                     └┘
2197    { rcases (lt_power_of_limit (ne_of_gt $ lt_trans zero_lt_one b1) h).1 this with ⟨a, h₁, h₂⟩,
id                                                                      
typ                                                                     
2198      exact (not_le_of_lt h₁).elim (le_omin.1 (le_refl t) a h₂) }
id                                                          
typ                                                         
st                                                                 └─
2199  end
st   ──┘
2200  
2201  theorem lt_power_succ_log {b : ordinal} (b1 : 1 < b) (x : ordinal) :
id                                  └──┘                     └┘  └─┘
src                                 └──┘                      └┘  └─┘
typ                                 └──┘                     └┘  └─┘
doc                                 └──┘                      └┘  └─┘
2202    x < b ^ succ (log b x) :=
id                      
typ                     
2203  begin
2204    cases lt_or_eq_of_le (zero_le x) with x0 x0,
2205    { rw [succ_log_def b1 x0], exact omin_mem {o | x < b^o} _ },
id                                                      
typ                                                     
st                                                               └┘
2206    { subst x, apply power_pos _ (lt_trans zero_lt_one b1) }
id             
typ            
st                                                            └─
2207  end
st   ──┘
2208  
2209  theorem power_log_le (b) {x : ordinal} (x0 : 0 < x) :
id                                 └──┘              
src                                └──┘  
typ                                └──┘              
doc                                └──┘  
2210    b ^ log b x ≤ x :=
id                
typ               
2211  begin
2212    by_cases b0 : b = 0,
2213    { rw [b0, zero_power'],
2214      refine le_trans (sub_le_self _ _) (one_le_iff_pos.2 x0) },
st                                                               └┘
2215    cases lt_or_eq_of_le (one_le_iff_ne_zero.2 b0) with b1 b1,
2216    { refine le_of_not_lt (λ h, not_le_of_lt (lt_succ_self (log b x)) _),
id                                                             └─┘  
src                                                            └─┘
typ                                                            └─┘  
doc                                                            └─┘
2217      have := @omin_le {o | x < b^o} _ _ h,
id                               
typ                              
2218      rwa ← succ_log_def b1 x0 at this },
st                                        └┘
2219    { rw [← b1, one_power], exact one_le_iff_pos.2 x0 }
st                                                       └─
2220  end
st   ──┘
2221  
2222  theorem le_log {b x c : ordinal} (b1 : 1 < b) (x0 : 0 < x) :
id                           └┘  └┘                         
src                          └┘  └┘
typ                          └┘  └┘                         
doc                          └┘  └┘
2223    c ≤ log b x ↔ b ^ c ≤ x :=
id                     
src                
typ                    
2224  ⟨λ h, le_trans ((power_le_power_iff_right b1).2 h) (power_log_le b x0),
id                                                                    
typ                                                                   
2225   λ h, le_of_not_lt $ λ hn,
2226     not_le_of_lt (lt_power_succ_log b1 x) $
id                                         
typ                                        
2227     le_trans ((power_le_power_iff_right b1).2 (succ_le.2 hn)) h⟩
2228  
2229  theorem log_lt {b x c : ordinal} (b1 : 1 < b) (x0 : 0 < x) :
id                           └┘  └┘                         
src                          └┘  └┘
typ                          └┘  └┘                         
doc                          └┘  └┘
2230    log b x < c ↔ x < b ^ c :=
id                     
src                
typ                    
2231  lt_iff_lt_of_le_iff_le (le_log b1 x0)
2232  
2233  theorem log_le_log (b) {x y : ordinal} (xy : x ≤ y) :
id                                   └┘             
src                                  └┘  
typ                                  └┘             
doc                                  └┘  
2234    log b x ≤ log b y :=
id                  
typ                 
2235  if x0 : x = 0 then by simp only [x0, log_zero, zero_le] else
id           
typ          
2236  have x0 : 0 < x, from pos_iff_ne_zero.2 x0,
id                 
typ                
2237  if b1 : 1 < b then
id               
typ              
2238    (le_log b1 (lt_of_lt_of_le x0 xy)).2 $ le_trans (power_log_le _ x0) xy
2239  else by simp only [log_not_one_lt b1, zero_le]
2240  
2241  theorem log_le_self (b x : ordinal) : log b x ≤ x :=
id                              └┘  └┘             
src                             └┘  └┘
typ                             └┘  └┘             
doc                             └┘  └┘
2242  if x0 : x = 0 then by simp only [x0, log_zero, zero_le] else
id           
typ          
2243  if b1 : 1 < b then
id               
typ              
2244    le_trans (le_power_self _ b1) (power_log_le b (pos_iff_ne_zero.2 x0))
id                                                 
typ                                                
2245  else by simp only [log_not_one_lt b1, zero_le]
2246  
2247  @[simp] theorem nat_cast_mul {m n : ℕ} : ((m * n : ℕ) : ordinal) = m * n :=
id                                                       └┘  └─┘       
src                                                        └┘  └─┘
typ                                                      └┘  └─┘       
doc    └──┘                                                  └┘  └─┘
2248  by induction n with n IH; [simp only [nat.cast_zero, nat.mul_zero, mul_zero],
2249    rw [nat.mul_succ, nat.cast_add, IH, nat.cast_succ, mul_add_one]]
st                                                                   
2250  
2251  @[simp] theorem nat_cast_power {m n : ℕ} : ((pow m n : ℕ) : ordinal) = m ^ n :=
id                                                           └┘  └─┘       
src                                                            └┘  └─┘
typ                                                          └┘  └─┘       
doc    └──┘                                                      └┘  └─┘
2252  by induction n with n IH; [simp only [nat.pow_zero, nat.cast_zero, power_zero, nat.cast_one],
2253    rw [nat.pow_succ, nat_cast_mul, IH, nat.cast_succ, ← succ_eq_add_one, power_succ]]
st                                                                                     
2254  
2255  @[simp] theorem nat_cast_le {m n : ℕ} : (m : ordinal) ≤ n ↔ m ≤ n :=
id                                              └┘  └─┘         
src                                              └┘  └─┘      
typ                                             └┘  └─┘         
doc    └──┘                                       └┘  └─┘
2256  by rw [← cardinal.ord_nat, ← cardinal.ord_nat,
2257         cardinal.ord_le_ord, cardinal.nat_cast_le]
st                                                   
2258  
2259  @[simp] theorem nat_cast_lt {m n : ℕ} : (m : ordinal) < n ↔ m < n :=
id                                              └┘  └─┘         
src                                              └┘  └─┘      
typ                                             └┘  └─┘         
doc    └──┘                                       └┘  └─┘
2260  by simp only [lt_iff_le_not_le, nat_cast_le]
2261  
2262  @[simp] theorem nat_cast_inj {m n : ℕ} : (m : ordinal) = n ↔ m = n :=
id                                               └┘  └─┘         
src                                               └┘  └─┘      
typ                                              └┘  └─┘         
doc    └──┘                                        └┘  └─┘
2263  by simp only [le_antisymm_iff, nat_cast_le]
2264  
2265  @[simp] theorem nat_cast_eq_zero {n : ℕ} : (n : ordinal) = 0 ↔ n = 0 :=
id                                                 └┘  └─┘       
src                                                 └┘  └─┘      
typ                                                └┘  └─┘       
doc    └──┘                                          └┘  └─┘
2266  @nat_cast_inj n 0
id                 
typ                
2267  
2268  @[simp] theorem nat_cast_ne_zero {n : ℕ} : (n : ordinal) ≠ 0 ↔ n ≠ 0 :=
id                                                  └───┘        
src                                                  └───┘       
typ                                                 └───┘        
doc    └──┘                                           └───┘
2269  not_congr nat_cast_eq_zero
2270  
2271  @[simp] theorem nat_cast_pos {n : ℕ} : (0 : ordinal) < n ↔ 0 < n :=
id                                              └┘  └─┘          
src                                             └┘  └─┘      
typ                                             └┘  └─┘          
doc    └──┘                                      └┘  └─┘
2272  @nat_cast_lt 0 n
id                  
typ                 
2273  
2274  @[simp] theorem nat_cast_sub {m n : ℕ} : ((m - n : ℕ) : ordinal) = m - n :=
id                                                        └┘ └┘        
src                                                         └┘ └┘
typ                                                       └┘ └┘        
doc    └──┘                                                   └┘ └┘
2275  (_root_.le_total m n).elim
id                     
typ                    
2276    (λ h, by rw [nat.sub_eq_zero_iff_le.2 h, sub_eq_zero_iff_le.2 (nat_cast_le.2 h)]; refl)
id                                                                                       └──┘
src                                                                                      └──┘
typ                                                                                      └──┘
doc                                                                                      └──┘
2277    (λ h, (add_left_cancel n).1 $ by rw [← nat.cast_add,
id                            
typ                           
2278       nat.add_sub_cancel' h, add_sub_cancel_of_le (nat_cast_le.2 h)])
st                                                                     
2279  
2280  @[simp] theorem nat_cast_div {m n : ℕ} : ((m / n : ℕ) : ordinal) = m / n :=
id                                                       └┘  └─┘       
src                                                        └┘  └─┘
typ                                                      └┘  └─┘       
doc    └──┘                                                  └┘  └─┘
2281  if n0 : n = 0 then by simp only [n0, nat.div_zero, nat.cast_zero, div_zero] else
id           
typ          
2282  have n0':_, from nat_cast_ne_zero.2 n0,
2283  le_antisymm
2284    (by rw [le_div n0', ← nat_cast_mul, nat_cast_le, mul_comm];
2285        apply nat.div_mul_le_self)
2286    (by rw [div_le n0', succ, ← nat.cast_succ, ← nat_cast_mul,
2287            nat_cast_lt, mul_comm, ← nat.div_lt_iff_lt_mul _ _ (nat.pos_of_ne_zero n0)];
2288        apply nat.lt_succ_self)
2289  
2290  @[simp] theorem nat_cast_mod {m n : ℕ} : ((m % n : ℕ) : ordinal) = m % n :=
id                                                       └┘  └─┘       
src                                                        └┘  └─┘
typ                                                      └┘  └─┘       
doc    └──┘                                                  └┘  └─┘
2291  by rw [← add_left_cancel (n*(m/n)), div_add_mod, ← nat_cast_div, ← nat_cast_mul, ← nat.cast_add,
2292         add_comm, nat.mod_add_div]
st                                   
2293  
2294  @[simp] theorem nat_le_card {o} {n : ℕ} : (n : cardinal) ≤ card o ↔ (n : ordinal) ≤ o :=
id                                                └┘  └──┘                 └──┘    
src                                                └┘  └──┘                   └──┘
typ                                               └┘  └──┘                 └──┘    
doc    └──┘                                         └┘  └──┘                    └──┘
2295  ⟨λ h, by rwa [← cardinal.ord_le, cardinal.ord_nat] at h,
2296   λ h, card_nat n ▸ card_le_card h⟩
id                  
typ                 
2297  
2298  @[simp] theorem nat_lt_card {o} {n : ℕ} : (n : cardinal) < card o ↔ (n : ordinal) < o :=
id                                                └┘  └──┘                 └──┘    
src                                                └┘  └──┘                   └──┘
typ                                               └┘  └──┘                 └──┘    
doc    └──┘                                         └┘  └──┘                    └──┘
2299  by rw [← succ_le, ← cardinal.succ_le, cardinal.nat_succ, nat_le_card]; refl
id                                                                          └──┘
src                                                                         └──┘
typ                                                                         └──┘
doc                                                                         └──┘
2300  
2301  @[simp] theorem card_lt_nat {o} {n : ℕ} : card o < n ↔ o < n :=
id                                                         
src                                                      
typ                                                        
doc    └──┘
2302  lt_iff_lt_of_le_iff_le nat_le_card
2303  
2304  @[simp] theorem card_le_nat {o} {n : ℕ} : card o ≤ n ↔ o ≤ n :=
id                                                         
src                                                      
typ                                                        
doc    └──┘
2305  le_iff_le_iff_lt_iff_lt.2 nat_lt_card
2306  
2307  @[simp] theorem card_eq_nat {o} {n : ℕ} : card o = n ↔ o = n :=
id                                                         
src                                                      
typ                                                        
doc    └──┘
2308  by simp only [le_antisymm_iff, card_le_nat, nat_le_card]
2309  
2310  @[simp] theorem type_fin (n : ℕ) : @type (fin n) (<) _ = n :=
id                                            └┘            
src                                           └┘
typ                                           └┘            
doc    └──┘
2311  by rw [← card_eq_nat, card_type, mk_fin]
st                                          
2312  
2313  @[simp] theorem lift_nat_cast (n : ℕ) : lift n = n :=
id                                                  
src                                     
typ                                                 
doc    └──┘
2314  by induction n with n ih; [simp only [nat.cast_zero, lift_zero],
2315    simp only [nat.cast_succ, lift_add, ih, lift_one]]
2316  
2317  theorem lift_type_fin (n : ℕ) : lift (@type (fin n) (<) _) = n :=
id                                               └┘             
src                                              └┘
typ                                              └┘             
2318  by simp only [type_fin, lift_nat_cast]
2319  
2320  theorem fintype_card (r : α → α → Prop) [is_well_order α r] [fintype α] : type r = fintype.card α :=
id                                                             └┘ └─┘                          
src                                                                └┘ └─┘
typ                                                            └┘ └─┘                          
doc                                                                └┘ └─┘
2321  by rw [← card_eq_nat, card_type, fintype_card]
st                                                
2322  
2323  end ordinal
2324  
2325  namespace cardinal
2326  open ordinal
2327  
2328  @[simp] theorem ord_omega : ord.{u} omega = ordinal.omega :=
id                                       └───┘   └─┘ └┘ └──┘ 
src                                      └───┘   └─┘ └┘ └──┘ 
typ                                      └───┘   └─┘ └┘ └──┘ 
doc    └──┘                              └───┘   └─┘ └┘ └──┘ 
2329  le_antisymm (ord_le.2 $ le_refl _) $
2330  le_of_forall_lt $ λ o h, begin
id                       
typ                      
2331    rcases ordinal.lt_lift_iff.1 h with ⟨o, rfl, h'⟩,
2332    rw [lt_ord, ← lift_card, ← lift_omega.{0 u},
2333        lift_lt, ← typein_enum (<) h'],
2334    exact lt_omega_iff_fintype.2 ⟨set.fintype_lt_nat _⟩
2335  end
st   └─┘
2336  
2337  @[simp] theorem add_one_of_omega_le {c} (h : omega ≤ c) : c + 1 = c :=
id                                                └───┘              
src                                               └───┘
typ                                               └───┘              
doc    └──┘                                       └───┘
2338  by rw [add_comm, ← card_ord c, ← card_one,
2339         ← card_add, one_add_of_omega_le];
2340     rwa [← ord_omega, ord_le_ord]
2341  
2342  end cardinal
2343  
2344  namespace ordinal
2345  
2346  theorem lt_omega {o : ordinal.{u}} : o < omega ↔ ∃ n : ℕ, o = n :=
id                         └┘  └─┘            └─┘              
src                        └┘  └─┘             └─┘         
typ                        └┘  └─┘            └─┘              
doc                        └┘  └─┘             └─┘
2347  by rw [← cardinal.ord_omega, cardinal.lt_ord, lt_omega]; simp only [card_eq_nat]
2348  
2349  theorem nat_lt_omega (n : ℕ) : (n : ordinal) < omega :=
id                                     └┘  └─┘     └─┘
src                                     └┘  └─┘     └─┘
typ                                    └┘  └─┘     └─┘
doc                                      └┘  └─┘     └─┘
2350  lt_omega.2 ⟨_, rfl⟩
2351  
2352  theorem omega_pos : 0 < omega := nat_lt_omega 0
id                           └───┘
src                          └───┘
typ                          └───┘
doc                          └───┘
2353  
2354  theorem omega_ne_zero : omega ≠ 0 := ne_of_gt omega_pos
id                           └───┘
src                          └───┘
typ                          └───┘
doc                          └───┘
2355  
2356  theorem one_lt_omega : 1 < omega := by simpa only [nat.cast_one] using nat_lt_omega 1
id                              └───┘
src                             └───┘
typ                             └───┘
doc                             └───┘
2357  
2358  theorem omega_is_limit : is_limit omega :=
id                            └┘  └┘   └───┘
src                           └┘  └┘   └───┘
typ                           └┘  └┘   └───┘
doc                           └┘  └┘   └───┘
2359  ⟨omega_ne_zero, λ o h,
id                     
typ                    
2360    let ⟨n, e⟩ := lt_omega.1 h in
2361    by rw [e]; exact nat_lt_omega (n+1)⟩
id                                    
typ                                   
2362  
2363  theorem omega_le {o : ordinal.{u}} : omega ≤ o ↔ ∀ n : ℕ, (n : ordinal) ≤ o :=
id                         └──┘          └───┘                  └┘ └┘     
src                        └──┘          └───┘                    └┘ └┘
typ                        └──┘          └───┘                  └┘ └┘     
doc                        └──┘          └───┘                      └┘ └┘
2364  ⟨λ h n, le_trans (le_of_lt (nat_lt_omega _)) h,
id        
typ       
2365   λ H, le_of_forall_lt $ λ a h,
id                             
typ                            
2366     let ⟨n, e⟩ := lt_omega.1 h in
2367     by rw [e, ← succ_le]; exact H (n+1)⟩
id                                     
typ                                    
2368  
2369  theorem nat_lt_limit {o} (h : is_limit o) : ∀ n : ℕ, (n : ordinal) < o
id                                 └┘  └┘                   └┘  └┘     
src                                └┘  └┘                     └┘  └┘
typ                                └┘  └┘                   └┘  └┘     
doc                                └┘  └┘                      └┘  └┘
2370  | 0     := lt_of_le_of_ne (zero_le o) h.1.symm
id                                        
typ                                       
2371  | (n+1) := h.2 _ (nat_lt_limit n)
id             
typ            
2372  
2373  theorem omega_le_of_is_limit {o} (h : is_limit o) : omega ≤ o :=
id                                         └┘  └┘       └───┘   
src                                        └┘  └┘        └───┘
typ                                        └┘  └┘       └───┘   
doc                                        └┘  └┘        └───┘
2374  omega_le.2 $ λ n, le_of_lt $ nat_lt_limit h n
id                                             
typ                                            
2375  
2376  theorem add_omega {a : ordinal} (h : a < omega) : a + omega = omega :=
id                            └──┘            └─┘        └─┘   └───┘
src                           └──┘             └─┘         └─┘   └───┘
typ                           └──┘            └─┘        └─┘   └───┘
doc                           └──┘             └─┘         └─┘   └───┘
2377  begin
2378    rcases lt_omega.1 h with ⟨n, rfl⟩,
2379    clear h, induction n with n IH,
id                        
typ                       
2380    { rw [nat.cast_zero, zero_add] },
st                                   └┘
2381    { rw [nat.cast_succ, add_assoc, one_add_of_omega_le (le_refl _), IH] }
st                                                                         └─
2382  end
st   ──┘
2383  
2384  theorem add_lt_omega {a b : ordinal} (ha : a < omega) (hb : b < omega) : a + b < omega :=
id                               └┘  └┘            └───┘            └─┘           └─┘
src                              └┘  └┘             └───┘             └─┘             └─┘
typ                              └┘  └┘            └───┘            └─┘           └─┘
doc                              └┘  └┘             └───┘             └─┘             └─┘
2385  match a, b, lt_omega.1 ha, lt_omega.1 hb with
id           
typ          
2386  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ := by rw [← nat.cast_add]; apply nat_lt_omega
2387  end
2388  
2389  theorem mul_lt_omega {a b : ordinal} (ha : a < omega) (hb : b < omega) : a * b < omega :=
id                               └┘  └┘            └───┘            └─┘           └─┘
src                              └┘  └┘             └───┘             └─┘             └─┘
typ                              └┘  └┘            └───┘            └─┘           └─┘
doc                              └┘  └┘             └───┘             └─┘             └─┘
2390  match a, b, lt_omega.1 ha, lt_omega.1 hb with
id           
typ          
2391  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ := by rw [← nat_cast_mul]; apply nat_lt_omega
2392  end
2393  
2394  theorem is_limit_iff_omega_dvd {a : ordinal} : is_limit a ↔ a ≠ 0 ∧ omega ∣ a :=
id                                       └──┘        └┘            └┘ └┘   
src                                      └──┘        └┘             └┘ └┘
typ                                      └──┘        └┘            └┘ └┘   
doc                                      └──┘        └┘               └┘ └┘
2395  begin
2396    refine ⟨λ l, ⟨l.1, ⟨a / omega, le_antisymm _ (mul_div_le _ _)⟩⟩, λ h, _⟩,
2397    { refine (limit_le l).2 (λ x hx, le_of_lt _),
id                               
typ                              
2398      rw [← div_lt omega_ne_zero, ← succ_le, le_div omega_ne_zero,
2399          mul_succ, add_le_of_limit omega_is_limit],
id                                     └────────────┘
src                                    └────────────┘
typ                                    └────────────┘
2400      intros b hb,
2401      rcases lt_omega.1 hb with ⟨n, rfl⟩,
2402      exact le_trans (add_le_add_right (mul_div_le _ _) _)
2403        (le_of_lt $ lt_sub.1 $ nat_lt_limit (sub_is_limit l hx) _) },
id                                                           
typ                                                          
st                                                                    └┘
2404    { rcases h with ⟨a0, b, rfl⟩,
2405      refine mul_is_limit_left omega_is_limit
id                                └────────────┘
src                               └────────────┘
typ                               └────────────┘
2406        (pos_iff_ne_zero.2 $ mt _ a0),
2407      intro e, simp only [e, mul_zero] }
st                                        └─
2408  end
st   ──┘
2409  
2410  local infixr ^ := @pow ordinal ordinal ordinal.has_pow
id                          └─────┘  └┘ └─┘   └┘  └┘  └┘  
src                         └─────┘  └┘ └─┘   └┘  └┘  └┘  
typ                         └─────┘  └┘ └─┘   └┘  └┘  └┘  
doc                         └─────┘  └┘ └─┘
2411  
2412  theorem power_lt_omega {a b : ordinal} (ha : a < omega) (hb : b < omega) : a ^ b < omega :=
id                                 └┘  └┘            └───┘            └─┘           └─┘
src                                └┘  └┘             └───┘             └─┘             └─┘
typ                                └┘  └┘            └───┘            └─┘           └─┘
doc                                └┘  └┘             └───┘             └─┘             └─┘
2413  match a, b, lt_omega.1 ha, lt_omega.1 hb with
id           
typ          
2414  | _, _, ⟨m, rfl⟩, ⟨n, rfl⟩ := by rw [← nat_cast_power]; apply nat_lt_omega
2415  end
2416  
2417  theorem add_omega_power {a b : ordinal} (h : a < omega ^ b) : a + omega ^ b = omega ^ b :=
id                                  └┘  └┘           └─┘           └───┘       └─┘   
src                                 └┘  └┘            └─┘             └───┘        └─┘
typ                                 └┘  └┘           └─┘           └───┘       └─┘   
doc                                 └┘  └┘            └─┘             └───┘        └─┘
2418  begin
2419    refine le_antisymm _ (le_add_left _ _),
2420    revert h, apply limit_rec_on b,
id                                  
typ                                 
2421    { intro h, rw [power_zero, ← succ_zero, lt_succ, le_zero] at h,
2422      rw [h, zero_add] },
st                       └┘
2423    { intros b _ h, rw [power_succ] at h,
2424      rcases (lt_mul_of_limit omega_is_limit).1 h with ⟨x, xo, ax⟩,
id                               └────────────┘
src                              └────────────┘
typ                              └────────────┘
2425      refine le_trans (add_le_add_right (le_of_lt ax) _) _,
2426      rw [power_succ, ← mul_add, add_omega xo] },
st                                               └┘
2427    { intros b l IH h, rcases (lt_power_of_limit omega_ne_zero l).1 h with ⟨x, xb, ax⟩,
id                                                                
typ                                                               
2428      refine (((add_is_normal a).trans (power_is_normal one_lt_omega))
id                               
typ                              
2429        .limit_le l).2 (λ y yb, _),
id                          
typ                         
2430      let z := max x y,
id                     
typ                    
2431      have := IH z (max_lt xb yb)
id                  
typ                 
2432        (lt_of_lt_of_le ax $ power_le_power_right omega_pos (le_max_left _ _)),
2433      exact le_trans (add_le_add_left (power_le_power_right omega_pos (le_max_right _ _)) _)
2434        (le_trans this (power_le_power_right omega_pos $ le_of_lt $ max_lt xb yb)) }
st                                                                                    └─
2435  end
st   ──┘
2436  
2437  theorem add_lt_omega_power {a b c : ordinal} (h₁ : a < omega ^ c) (h₂ : b < omega ^ c) :
id                                       └┘  └┘             └───┘              └───┘   
src                                      └┘  └┘             └───┘                └───┘
typ                                      └┘  └┘             └───┘              └───┘   
doc                                      └┘  └┘             └───┘                └───┘
2438    a + b < omega ^ c :=
id            └───┘   
src            └───┘
typ           └───┘   
doc            └───┘
2439  by rwa [← add_omega_power h₁, add_lt_add_iff_left]
2440  
2441  theorem add_absorp {a b c : ordinal} (h₁ : a < omega ^ b) (h₂ : omega ^ b ≤ c) : a + c = c :=
id                               └┘  └┘             └───┘           └┘ └┘                
src                              └┘  └┘             └───┘            └┘ └┘
typ                              └┘  └┘             └───┘           └┘ └┘                
doc                              └┘  └┘             └───┘            └┘ └┘
2442  by rw [← add_sub_cancel_of_le h₂, ← add_assoc, add_omega_power h₁]
st                                                                    
2443  
2444  theorem add_absorp_iff {o : ordinal} (o0 : o > 0) : (∀ a < o, a + o = o) ↔ ∃ a, o = omega ^ a :=
id                               └──┘                                             └┘    
src                              └──┘                                                    └┘
typ                              └──┘                                             └┘    
doc                              └──┘                                                    └┘
2445  ⟨λ H, ⟨log omega o, begin
id              └─┘  
src             └─┘ 
typ             └─┘  
doc             └─┘ 
2446    refine ((lt_or_eq_of_le (power_log_le _ o0))
2447      .resolve_left $ λ h, _).symm,
2448    have := H _ h,
2449    have := lt_power_succ_log one_lt_omega o,
id                                            
typ                                           
2450    rw [power_succ, lt_mul_of_limit omega_is_limit] at this,
id                                     └────────────┘
src                                    └────────────┘
typ                                    └────────────┘
2451    rcases this with ⟨a, ao, h'⟩,
2452    rcases lt_omega.1 ao with ⟨n, rfl⟩, clear ao,
2453    revert h', apply not_lt_of_le,
2454    suffices e : omega ^ log omega o * ↑n + o = o,
id                          └─┘ └───┘             
src                         └─┘ └───┘
typ                         └─┘ └───┘             
doc                         └─┘ └───┘
2455    { simpa only [e] using le_add_right (omega ^ log omega o * ↑n) o },
id                                                  └─┘ └───┘        
src                                                 └─┘ └───┘
typ                                                 └─┘ └───┘        
doc                                                 └─┘ └───┘
st                                                                      └┘
2456    induction n with n IH, {simp only [nat.cast_zero, mul_zero, zero_add]},
id               
typ              
st                                                                          └┘
2457    simp only [nat.cast_succ, mul_add_one, add_assoc, this, IH]
2458  end⟩,
st   └─┘
2459  λ ⟨b, e⟩, e.symm ▸ λ a, add_omega_power⟩
id                        
typ                       
2460  
2461  theorem add_mul_limit_aux {a b c : ordinal} (ba : b + a = a)
id                                      └┘  └┘                
src                                     └┘  └┘
typ                                     └┘  └┘                
doc                                     └┘  └┘
2462    (l : is_limit c)
id          └┘  └┘   
src         └┘  └┘
typ         └┘  └┘   
doc         └┘  └┘
2463    (IH : ∀ c' < c, (a + b) * succ c' = a * succ c' + b) :
id                                 └┘           └┘   
typ                                └┘           └┘   
2464    (a + b) * c = a * c :=
id                   
typ                  
2465  le_antisymm
2466    ((mul_le_of_limit l).2 $ λ c' h, begin
id                               └┘
typ                              └┘
2467      apply le_trans (mul_le_mul_left _ (le_of_lt $ lt_succ_self _)),
2468      rw IH _ h,
2469      apply le_trans (add_le_add_left _ _),
2470      { rw ← mul_succ, exact mul_le_mul_left _ (succ_le.2 $ l.2 _ h) },
id                                                             
typ                                                            
st                                                                      └┘
2471      { rw ← ba, exact le_add_right _ _ }
st                                         └┘
2472    end)
st     └─┘
2473    (mul_le_mul_right _ (le_add_right _ _))
2474  
2475  theorem add_mul_succ {a b : ordinal} (c) (ba : b + a = a) :
id                               └┘  └┘                   
src                              └┘  └┘
typ                              └┘  └┘                   
doc                              └┘  └┘
2476    (a + b) * succ c = a * succ c + b :=
id                                
typ                               
2477  begin
2478    apply limit_rec_on c,
2479    { simp only [succ_zero, mul_one] },
st                                      └┘
2480    { intros c IH,
2481      rw [mul_succ, IH, ← add_assoc, add_assoc _ b, ba, ← mul_succ] },
id                                                  
typ                                                 
st                                                                    └┘
2482    { intros c l IH,
2483      have := add_mul_limit_aux ba l IH,
id                                    
typ                                   
2484      rw [mul_succ, add_mul_limit_aux ba l IH, mul_succ, add_assoc] }
id                                          
typ                                         
st                                                                    └─
2485  end
st   ──┘
2486  
2487  theorem add_mul_limit {a b c : ordinal} (ba : b + a = a)
id                                  └┘  └┘                
src                                 └┘  └┘
typ                                 └┘  └┘                
doc                                 └┘  └┘
2488    (l : is_limit c) : (a + b) * c = a * c :=
id          └┘  └┘                     
src         └┘  └┘
typ         └┘  └┘                     
doc         └┘  └┘
2489  add_mul_limit_aux ba l (λ c' _, add_mul_succ c' ba)
id                            └┘                 └┘
typ                           └┘                 └┘
2490  
2491  theorem mul_omega {a : ordinal} (a0 : 0 < a) (ha : a < omega) : a * omega = omega :=
id                           └──┘                         └───┘        └─┘   └───┘
src                          └──┘                           └───┘         └─┘   └───┘
typ                          └──┘                         └───┘        └─┘   └───┘
doc                          └──┘                           └───┘         └─┘   └───┘
2492  le_antisymm
2493    ((mul_le_of_limit omega_is_limit).2 $ λ b hb, le_of_lt (mul_lt_omega ha hb))
id                       └┘  └┘  └┘  └┘
src                      └┘  └┘  └┘  └┘
typ                      └┘  └┘  └┘  └┘
2494    (by simpa only [one_mul] using mul_le_mul_right omega (one_le_iff_pos.2 a0))
id                                                     └───┘
src                                                    └───┘
typ                                                    └───┘
doc                                                    └───┘
2495  
2496  theorem mul_lt_omega_power {a b c : ordinal}
id                                       └┘  └┘
src                                      └┘  └┘
typ                                      └┘  └┘
doc                                      └┘  └┘
2497    (c0 : 0 < c) (ha : a < omega ^ c) (hb : b < omega) : a * b < omega ^ c :=
id                          └───┘              └───┘          └───┘   
src                           └───┘                └───┘            └───┘
typ                         └───┘              └───┘          └───┘   
doc                           └───┘                └───┘            └───┘
2498  if b0 : b = 0 then by simp only [b0, mul_zero, power_pos _ omega_pos] else begin
id           
typ          
2499    rcases zero_or_succ_or_limit c with rfl|⟨c,rfl⟩|l,
id                                  
typ                                 
2500    { exact (lt_irrefl _).elim c0 },
st                                   └┘
2501    { rw power_succ at ha,
2502      rcases ((mul_is_normal $ power_pos _ omega_pos).limit_lt
2503        omega_is_limit).1 ha with ⟨n, hn, an⟩,
id         └────────────┘
src        └────────────┘
typ        └────────────┘
2504      refine lt_of_le_of_lt (mul_le_mul_right _ (le_of_lt an)) _,
2505      rw [power_succ, mul_assoc, mul_lt_mul_iff_left (power_pos _ omega_pos)],
2506      exact mul_lt_omega hn hb },
st                                └┘
2507    { rcases ((power_is_normal one_lt_omega).limit_lt l).1 ha with ⟨x, hx, ax⟩,
id                                                       
typ                                                      
2508      refine lt_of_le_of_lt (mul_le_mul (le_of_lt ax) (le_of_lt hb)) _,
2509      rw [← power_succ, power_lt_power_iff_right one_lt_omega],
2510      exact l.2 _ hx }
id             
typ            
st                      └┘
2511  end
2512  
2513  theorem mul_omega_dvd {a : ordinal}
id                              └──┘  
src                             └──┘  
typ                             └──┘  
doc                             └──┘  
2514    (a0 : 0 < a) (ha : a < omega) : ∀ {b}, omega ∣ b → a * b = b
id                          └───┘           └──┘             
src                           └───┘           └──┘
typ                         └───┘           └──┘             
doc                           └───┘           └──┘
2515  | _ ⟨b, rfl⟩ := by rw [← mul_assoc, mul_omega a0 ha]
st                                                      
2516  
2517  theorem mul_omega_power_power {a b : ordinal} (a0 : 0 < a) (h : a < omega ^ omega ^ b) :
id                                        └┘  └┘                       └───┘   └─┘    
src                                       └┘  └┘                         └───┘   └─┘ 
typ                                       └┘  └┘                       └───┘   └─┘    
doc                                       └┘  └┘                         └───┘   └─┘ 
2518    a * omega ^ omega ^ b = omega ^ omega ^ b :=
id        └───┘    └─┘      └─┘    └───┘   
src        └───┘    └─┘       └─┘    └───┘
typ       └───┘    └─┘      └─┘    └───┘   
doc        └───┘    └─┘       └─┘    └───┘
2519  begin
2520    by_cases b0 : b = 0, {rw [b0, power_zero, power_one] at h ⊢, exact mul_omega a0 h},
st                                                                                      └┘
2521    refine le_antisymm _ (by simpa only [one_mul] using mul_le_mul_right (omega^omega^b) (one_le_iff_pos.2 a0)),
id                                                                                 └───┘ 
src                                                                                └───┘
typ                                                                                └───┘ 
doc                                                                                └───┘
2522    rcases (lt_power_of_limit omega_ne_zero (power_is_limit_left omega_is_limit b0)).1 h
id                                                                  └────────────┘
src                                                                 └────────────┘
typ                                                                 └────────────┘
2523      with ⟨x, xb, ax⟩,
2524    refine le_trans (mul_le_mul_right _ (le_of_lt ax)) _,
2525    rw [← power_add, add_omega_power xb]
st                                        
2526  end
st   └─┘
2527  
2528  theorem power_omega {a : ordinal} (a1 : 1 < a) (h : a < omega) : a ^ omega = omega :=
id                            └──┘                        └─┘         └─┘   └───┘
src                           └──┘                          └─┘          └─┘   └───┘
typ                           └──┘                        └─┘         └─┘   └───┘
doc                           └──┘                          └─┘          └─┘   └───┘
2529  le_antisymm
2530    ((power_le_of_limit (one_le_iff_ne_zero.1 $ le_of_lt a1) omega_is_limit).2
id                                                              └┘  └┘  └┘  └┘
src                                                             └┘  └┘  └┘  └┘
typ                                                             └┘  └┘  └┘  └┘
2531      (λ b hb, le_of_lt (power_lt_omega h hb)))
id          
typ         
2532    (le_power_self _ a1)
2533  
2534  theorem CNF_aux {b o : ordinal} (b0 : b ≠ 0) (o0 : o ≠ 0) :
id                            └┘                      
src                           └┘
typ                           └┘                      
doc                           └┘
2535    o % b ^ log b o < o :=
id                   
typ                  
2536  lt_of_lt_of_le
2537    (mod_lt _ $ power_ne_zero _ b0)
2538    (power_log_le _ $ pos_iff_ne_zero.2 o0)
2539  
2540  @[elab_as_eliminator] noncomputable def CNF_rec {b : ordinal} (b0 : b ≠ 0)
id                                                          └──┘
src                                                         └──┘
typ                                                         └──┘
doc    └────────────────┘                                   └──┘
2541    {C : ordinal → Sort*}
id          └┘  └┘
src         └┘  └┘
typ         └┘  └┘
doc         └┘  └┘
2542    (H0 : C 0)
2543    (H : ∀ o, o ≠ 0 → o % b ^ log b o < o → C (o % b ^ log b o) → C o)
id                                                        
typ                                                       
2544    : ∀ o, C o
id             
typ            
2545  | o :=
id     
typ    
2546    if o0 : o = 0 then by rw o0; exact H0 else
2547    have _, from CNF_aux b0 o0,
2548    H o o0 this (CNF_rec (o % b ^ log b o))
id                                      
typ                                     
2549  using_well_founded {dec_tac := `[assumption]}
2550  
2551  @[simp] theorem CNF_rec_zero {b} (b0) {C H0 H} : @CNF_rec b b0 C H0 H 0 = H0 :=
id                                                                 
typ                                                                
doc    └──┘
2552  by rw [CNF_rec, dif_pos rfl]; refl
id                                 └──┘
src                                └──┘
typ                                └──┘
doc                                └──┘
2553  
2554  @[simp] theorem CNF_rec_ne_zero {b} (b0) {C H0 H o} (o0) :
doc    └──┘
2555    @CNF_rec b b0 C H0 H o = H o o0 (CNF_aux b0 o0) (@CNF_rec b b0 C H0 H _) :=
id                                                               
typ                                                              
2556  by rw [CNF_rec, dif_neg o0]
2557  
2558  /-- The Cantor normal form of an ordinal is the list of coefficients
2559    in the base-`b` expansion of `o`.
2560  
2561      CNF b (b ^ u₁ * v₁ + b ^ u₂ * v₂) = [(u₁, v₁), (u₂, v₂)] -/
2562  def CNF (b := omega) (o : ordinal) : list (ordinal × ordinal) :=
id                             └──┘            └──┘     └──┘  
src                            └──┘            └──┘     └──┘  
typ                            └──┘            └──┘     └──┘  
doc                            └──┘            └──┘     └──┘  
2563  if b0 : b = 0 then [] else
2564  CNF_rec b0 [] (λ o o0 h IH, (log b o, o / b ^ log b o) :: IH) o
id                                                            
typ                                                           
2565  
2566  @[simp] theorem zero_CNF (o) : CNF 0 o = [] :=
id                                        
typ                                       
doc    └──┘
2567  dif_pos rfl
2568  
2569  @[simp] theorem CNF_zero (b) : CNF b 0 = [] :=
id                                      
typ                                     
doc    └──┘
2570  if b0 : b = 0 then dif_pos b0 else
2571  (dif_neg b0).trans $ CNF_rec_zero _
2572  
2573  theorem CNF_ne_zero {b o : ordinal} (b0 : b ≠ 0) (o0 : o ≠ 0) :
id                                └┘                      
src                               └┘  
typ                               └┘                      
doc                               └┘  
2574    CNF b o = (log b o, o / b ^ log b o) :: CNF b (o % b ^ log b o) :=
id                                                      
typ                                                     
2575  by unfold CNF; rw [dif_neg b0, dif_neg b0, CNF_rec_ne_zero b0 o0]
st                                                                   
2576  
2577  theorem one_CNF {o : ordinal} (o0 : o ≠ 0) :
id                        └──┘          
src                       └──┘  
typ                       └──┘          
doc                       └──┘  
2578    CNF 1 o = [(0, o)] :=
id                   
typ                  
2579  by rw [CNF_ne_zero one_ne_zero o0, log_not_one_lt (lt_irrefl _), power_zero, mod_one, CNF_zero, div_one]
st                                                                                                          
2580  
2581  theorem CNF_foldr {b : ordinal} (b0 : b ≠ 0) (o) :
id                          └──┘          
src                         └──┘  
typ                         └──┘          
doc                         └──┘  
2582    (CNF b o).foldr (λ p r, b ^ p.1 * p.2 + r) 0 = o :=
id                                            
typ                                           
2583  CNF_rec b0 (by rw CNF_zero; refl)
id                               └──┘
src                              └──┘
typ                              └──┘
doc                              └──┘
2584    (λ o o0 h IH, by rw [CNF_ne_zero b0 o0, list.foldr_cons, IH, div_add_mod]) o
id                                                                               
typ                                                                              
st                                                                             
2585  
2586  theorem CNF_pairwise_aux (b := omega) (o) :
2587    (∀ p ∈ CNF b o, prod.fst p ≤ log b o) ∧
id                                      
src                                          
typ                                     
2588    (CNF b o).pairwise (λ p q, q.1 < p.1) :=
id           
typ          
2589  begin
2590    by_cases b0 : b = 0,
id                   
typ                  
2591    { simp only [b0, zero_CNF, list.pairwise.nil, and_true], exact λ _, false.elim },
id                                                                      
typ                                                                     
st                                                                                    └┘
2592    cases lt_or_eq_of_le (one_le_iff_ne_zero.2 b0) with b1 b1,
2593    { refine CNF_rec b0 _ _ o,
id                             
typ                            
2594      { simp only [CNF_zero, list.pairwise.nil, and_true], exact λ _, false.elim },
id                                                                    
typ                                                                   
st                                                                                  └┘
2595      intros o o0 H IH, cases IH with IH₁ IH₂,
2596      simp only [CNF_ne_zero b0 o0, list.forall_mem_cons, list.pairwise_cons, IH₂, and_true],
2597      refine ⟨⟨le_refl _, λ p m, _⟩, λ p m, _⟩,
id                                       
typ                                      
2598      { exact le_trans (IH₁ p m) (log_le_log _ $ le_of_lt H) },
id                             
typ                            
st                                                              └┘
2599      { refine lt_of_le_of_lt (IH₁ p m) ((log_lt b1 _).2 _),
id                                    
typ                                   
2600        { rw pos_iff_ne_zero, intro e,
2601          rw e at m, simpa only [CNF_zero] using m },
st                                                    └┘
2602        { exact mod_lt _ (power_ne_zero _ b0) } } },
st                                               └────┘
2603    { by_cases o0 : o = 0,
id                     
typ                    
2604      { simp only [o0, CNF_zero, list.pairwise.nil, and_true], exact λ _, false.elim },
id                                                                        
typ                                                                       
st                                                                                      └┘
2605      rw [← b1, one_CNF o0],
2606      simp only [list.mem_singleton, log_not_one_lt (lt_irrefl _), forall_eq, le_refl, true_and, list.pairwise_singleton] }
st                                                                                                                           └─
2607  end
st   ──┘
2608  
2609  theorem CNF_pairwise (b := omega) (o) :
2610    (CNF b o).pairwise (λ p q, prod.fst q < p.1) :=
id                                         
typ                                        
2611  (CNF_pairwise_aux _ _).2
2612  
2613  theorem CNF_fst_le_log (b := omega) (o) :
2614    ∀ p ∈ CNF b o, prod.fst p ≤ log b o :=
id                                   
typ                                  
2615  (CNF_pairwise_aux _ _).1
2616  
2617  theorem CNF_fst_le (b := omega) (o) (p ∈ CNF b o) : prod.fst p ≤ o :=
id                                                                
typ                                                               
2618  le_trans (CNF_fst_le_log _ _ p H) (log_le_self _ _)
id                                
typ                               
2619  
2620  theorem CNF_snd_lt {b : ordinal} (b1 : 1 < b) (o) :
id                            └┘ └┘             
src                           └┘ └┘
typ                           └┘ └┘             
doc                           └┘ └┘
2621    ∀ p ∈ CNF b o, prod.snd p < b :=
id                              
typ                             
2622  begin
2623    have b0 := ne_of_gt (lt_trans zero_lt_one b1),
2624    refine CNF_rec b0 (λ _, by rw [CNF_zero]; exact false.elim) _ o,
id                                                                  
typ                                                                 
2625    intros o o0 H IH,
2626    simp only [CNF_ne_zero b0 o0, list.mem_cons_iff, list.forall_mem_cons', iff_true_intro IH, and_true],
2627    rw [div_lt (power_ne_zero _ b0), ← power_succ],
2628    exact lt_power_succ_log b1 _,
2629  end
st   └─┘
2630  
2631  theorem CNF_sorted (b := omega) (o) :
2632    ((CNF b o).map prod.fst).sorted (>) :=
id            
typ           
2633  by rw [list.sorted, list.pairwise_map]; exact CNF_pairwise b o
id                                                               
typ                                                              
2634  
2635  /-- The next fixed point function, the least fixed point of the
2636    normal function `f` above `a`. -/
2637  def nfp (f : ordinal → ordinal) (a : ordinal) :=
id                └┘  └┘     └┘ └┘       └───┘
src               └┘  └┘     └┘ └┘       └───┘
typ               └┘  └┘     └┘ └┘       └───┘
doc               └┘  └┘     └┘ └┘       └───┘
2638  sup (λ n : ℕ, f^[n] a)
id                    
src             
typ                   
2639  
2640  theorem iterate_le_nfp (f a n) : f^[n] a ≤ nfp f a :=
id                                                 
typ                                                
2641  le_sup _ n
id            
typ           
2642  
2643  theorem le_nfp_self (f a) : a ≤ nfp f a :=
id                                       
typ                                      
2644  iterate_le_nfp f a 0
id                   
typ                  
2645  
2646  theorem is_normal.lt_nfp {f} (H : is_normal f) {a b} :
2647    f b < nfp f a ↔ b < nfp f a :=
id                         
typ                        
2648  lt_sup.trans $ iff.trans
2649    (by exact
2650     ⟨λ ⟨n, h⟩, ⟨n, lt_of_le_of_lt (H.le_self _) h⟩,
2651      λ ⟨n, h⟩, ⟨n+1, by rw nat.iterate_succ'; exact H.lt_iff.2 h⟩⟩)
2652    lt_sup.symm
2653  
2654  theorem is_normal.nfp_le {f} (H : is_normal f) {a b} :
id                                               
typ                                              
2655    nfp f a ≤ f b ↔ nfp f a ≤ b :=
id                         
typ                        
2656  le_iff_le_iff_lt_iff_lt.2 H.lt_nfp
id                             
typ                            
2657  
2658  theorem is_normal.nfp_le_fp {f} (H : is_normal f) {a b}
id                                                  
typ                                                 
2659    (ab : a ≤ b) (h : f b ≤ b) : nfp f a ≤ b :=
id                                     
typ                                    
2660  sup_le.2 $ λ i, begin
id                
typ               
2661    induction i with i IH generalizing a, {exact ab},
st                                                    └┘
2662    exact IH (le_trans (H.le_iff.2 ab) h),
2663  end
st   └─┘
2664  
2665  theorem is_normal.nfp_fp {f} (H : is_normal f) (a) : f (nfp f a) = nfp f a :=
id                                                                        
typ                                                                       
2666  begin
2667    refine le_antisymm _ (H.le_self _),
2668    cases le_or_lt (f a) a with aa aa,
id                         
typ                        
2669    { rwa le_antisymm (H.nfp_le_fp (le_refl _) aa) (le_nfp_self _ _) },
st                                                                      └┘
2670    rcases zero_or_succ_or_limit (nfp f a) with e|⟨b, e⟩|l,
id                                        
typ                                       
2671    { refine @le_trans _ _ _ (f a) _ (H.le_iff.2 _) (iterate_le_nfp f a 1),
id                                                                       
typ                                                                      
2672      simp only [e, zero_le] },
st                              └┘
2673    { have : f b < nfp f a := H.lt_nfp.2 (by simp only [e, lt_succ_self]),
id                         
typ                        
2674      rw [e, lt_succ] at this,
2675      have ab : a ≤ b,
id                    
typ                   
2676      { rw [← lt_succ, ← e],
2677        exact lt_of_lt_of_le aa (iterate_le_nfp f a 1) },
id                                                  
typ                                                 
st                                                        └┘
2678      refine le_trans (H.le_iff.2 (H.nfp_le_fp ab this))
2679        (le_trans this (le_of_lt _)),
2680      simp only [e, lt_succ_self] },
st                                   └┘
2681    { exact (H.2 _ l _).2 (λ b h, le_of_lt (H.lt_nfp.2 h)) }
id                             
typ                            
st                                                            └─
2682  end
st   ──┘
2683  
2684  theorem is_normal.le_nfp {f} (H : is_normal f) {a b} :
id                                               
typ                                              
2685    f b ≤ nfp f a ↔ b ≤ nfp f a :=
id                         
typ                        
2686  ⟨le_trans (H.le_self _), λ h,
id              
typ             
2687    by simpa only [H.nfp_fp] using H.le_iff.2 h⟩
2688  
2689  theorem nfp_eq_self {f : ordinal → ordinal} {a} (h : f a = a) : nfp f a = a :=
id                            └┘  └┘     └┘ └┘                            
src                           └┘  └┘     └┘ └┘
typ                           └┘  └┘     └┘ └┘                            
doc                           └┘  └┘     └┘ └┘
2690  le_antisymm (sup_le.mpr $ λ i, by rw [nat.iterate₀ h]) (le_nfp_self f a)
id                                                                       
typ                                                                      
2691  
2692  /-- The derivative of a normal function `f` is
2693    the sequence of fixed points of `f`. -/
2694  def deriv (f : ordinal → ordinal) (o : ordinal) : ordinal :=
id                  └┘  └┘     └┘ └┘       └───┘      └─────┘
src                 └┘  └┘     └┘ └┘       └───┘      └─────┘
typ                 └┘  └┘     └┘ └┘       └───┘      └─────┘
doc                 └┘  └┘     └┘ └┘       └───┘      └─────┘
2695  limit_rec_on o (nfp f 0)
id                      
typ                     
2696    (λ a IH, nfp f (succ IH))
id         └┘             └┘
typ        └┘             └┘
2697    (λ a l, bsup.{u u} a)
id                       
typ                      
2698  
2699  @[simp] theorem deriv_zero (f) : deriv f 0 = nfp f 0 := limit_rec_on_zero _ _ _
id                                                   
typ                                                  
doc     └┘
2700  
2701  @[simp] theorem deriv_succ (f o) : deriv f (succ o) = nfp f (succ (deriv f o)) :=
id                                                                          
typ                                                                         
doc    └──┘
2702  limit_rec_on_succ _ _ _ _
2703  
2704  theorem deriv_limit (f) {o} : is_limit o →
id                                          
typ                                         
2705    deriv f o = bsup.{u u} o (λ a _, deriv f a) :=
id                                         
typ                                        
2706  limit_rec_on_limit _ _ _ _
2707  
2708  theorem deriv_is_normal (f) : is_normal (deriv f) :=
id                                                  
typ                                                 
2709  ⟨λ o, by rw [deriv_succ, ← succ_le]; apply le_nfp_self,
id      
typ     
2710   λ o l a, by rw [deriv_limit _ l, bsup_le]⟩
id                               
typ                              
st                                            
2711  
2712  theorem is_normal.deriv_fp {f} (H : is_normal f) (o) : f (deriv.{u} f o) = deriv f o :=
id                                                                                 
typ                                                                                
2713  begin
2714    apply limit_rec_on o,
2715    { rw [deriv_zero, H.nfp_fp] },
st                                └┘
2716    { intros o ih, rw [deriv_succ, H.nfp_fp] },
st                                             └┘
2717    intros o l IH,
2718    rw [deriv_limit _ l, is_normal.bsup.{u u u} H _ l.1],
id                                                   
typ                                                  
2719    refine eq_of_forall_ge_iff (λ c, _),
id                                   
typ                                  
2720    simp only [bsup_le, IH] {contextual:=tt}
id                                          └┘
src                                         └┘
typ                                         └┘
2721  end
st   └─┘
2722  
2723  theorem is_normal.fp_iff_deriv {f} (H : is_normal f)
id                                                     
typ                                                    
2724    {a} : f a ≤ a ↔ ∃ o, a = deriv f o :=
id                                
src                  
typ                               
2725  ⟨λ ha, begin
2726    suffices : ∀ o (_:a ≤ deriv f o), ∃ o, a = deriv f o,
id                                          
typ                                         
2727    from this a ((deriv_is_normal _).le_self _),
id               
typ              
2728    intro o, apply limit_rec_on o,
id                                 
typ                                
2729    { intros h₁,
2730      refine ⟨0, le_antisymm h₁ _⟩,
2731      rw deriv_zero,
2732      exact H.nfp_le_fp (zero_le _) ha },
st                                        └┘
2733    { intros o IH h₁,
2734      cases le_or_lt a (deriv f o), {exact IH h},
id                               
typ                              
st                                                └┘
2735      refine ⟨succ o, le_antisymm h₁ _⟩,
id               └──┘ 
src              └──┘
typ              └──┘ 
doc              └──┘
2736      rw deriv_succ,
2737      exact H.nfp_le_fp (succ_le.2 h) ha },
st                                          └┘
2738    { intros o l IH h₁,
2739      cases eq_or_lt_of_le h₁, {exact ⟨_, h⟩},
st                                             └┘
2740      rw [deriv_limit _ l, ← not_le, bsup_le, not_ball] at h,
id                         
typ                        
2741      exact let ⟨o', h, hl⟩ := h in IH o' h (le_of_not_le hl) }
id                  └┘
typ                 └┘
st                                                               └─
2742  end, λ ⟨o, e⟩, e.symm ▸ le_of_eq (H.deriv_fp _)⟩
id                                     
typ                                    
st   ──┘
2743  
2744  end ordinal
2745  
2746  namespace cardinal
2747  section using_ordinals
2748  open ordinal
2749  
2750  theorem ord_is_limit {c} (co : omega ≤ c) : (ord c).is_limit :=
id                                  └──┘              └──┘  └┘
src                                 └──┘                └──┘  └┘
typ                                 └──┘              └──┘  └┘
doc                                 └──┘                └──┘  └┘
2751  begin
2752    refine ⟨λ h, omega_ne_zero _, λ a, lt_imp_lt_of_le_imp_le _⟩,
2753    { rw [← ordinal.le_zero, ord_le] at h,
2754      simpa only [card_zero, le_zero] using le_trans co h },
st                                                           └┘
2755    { intro h, rw [ord_le] at h ⊢,
2756      rwa [← @add_one_of_omega_le (card a), ← card_succ],
id                                    └──┘ 
src                                   └──┘
typ                                   └──┘ 
doc                                   └──┘
2757      rw [← ord_le, ← le_succ_of_is_limit, ord_le],
2758      { exact le_trans co h },
st                             └┘
2759      { rw ord_omega, exact omega_is_limit } }
id                             └────────────┘
src                            └────────────┘
typ                            └────────────┘
st                                            └───
2760  end
st   ──┘
2761  
2762  def aleph_idx.initial_seg : @initial_seg cardinal ordinal (<) (<) :=
id                                            └──┘  └┘ └┘  └─┘
src                                           └──┘  └┘ └┘  └─┘
typ                                           └──┘  └┘ └┘  └─┘
doc                                           └──┘  └┘ └┘  └─┘
2763  @order_embedding.collapse cardinal ordinal (<) (<) _ cardinal.ord.order_embedding
id                             └──┘  └┘ └┘  └─┘
src                            └──┘  └┘ └┘  └─┘
typ                            └──┘  └┘ └┘  └─┘
doc                            └──┘  └┘ └┘  └─┘
2764  
2765  /-- The `aleph'` index function, which gives the ordinal index of a cardinal.
2766    (The `aleph'` part is because unlike `aleph` this counts also the
2767    finite stages. So `aleph_idx n = n`, `aleph_idx ω = ω`,
2768    `aleph_idx ℵ₁ = ω + 1` and so on.)  -/
2769  def aleph_idx : cardinal → ordinal := aleph_idx.initial_seg
id                     └┘  └┘     └──┘
src                    └┘  └┘     └──┘
typ                    └┘  └┘     └──┘
doc                    └┘  └┘     └──┘
2770  
2771  @[simp] theorem aleph_idx.initial_seg_coe :
doc    └──┘
2772    (aleph_idx.initial_seg : cardinal → ordinal) = aleph_idx := rfl
id                              └┘  └┘     └──┘  
src                             └┘  └┘     └──┘  
typ                             └┘  └┘     └──┘  
doc                             └┘  └┘     └──┘  
2773  
2774  @[simp] theorem aleph_idx_lt {a b} : aleph_idx a < aleph_idx b ↔ a < b :=
id                                                                    
src                                                                 
typ                                                                   
doc    └──┘
2775  aleph_idx.initial_seg.to_order_embedding.ord'.symm
2776  
2777  @[simp] theorem aleph_idx_le {a b} : aleph_idx a ≤ aleph_idx b ↔ a ≤ b :=
id                                                                    
src                                                                 
typ                                                                   
doc    └──┘
2778  by rw [← not_lt, ← not_lt, aleph_idx_lt]
st                                          
2779  
2780  theorem aleph_idx.init {a b} : b < aleph_idx a → ∃ c, aleph_idx c = b :=
id                                                                   
typ                                                                  
2781  aleph_idx.initial_seg.init _ _
2782  
2783  def aleph_idx.order_iso : @order_iso cardinal.{u} ordinal.{u} (<) (<) :=
id                                        └──┘  └┘     └┘  └─┘
src                                       └──┘  └┘     └┘  └─┘
typ                                       └──┘  └┘     └┘  └─┘
doc                                       └──┘  └┘     └┘  └─┘
2784  @order_iso.of_surjective cardinal.{u} ordinal.{u} (<) (<) aleph_idx.initial_seg.{u} $
id                            └──┘  └┘      └──┘
src                           └──┘  └┘      └──┘
typ                           └──┘  └┘      └──┘
doc                           └──┘  └┘      └──┘
2785  (initial_seg.eq_or_principal aleph_idx.initial_seg.{u}).resolve_right $
2786  λ ⟨o, e⟩, begin
2787    have : ∀ c, aleph_idx c < o := λ c, (e _).2 ⟨_, rfl⟩,
id                └───────┘           
src                └───────┘
typ               └───────┘           
doc                └───────┘
2788    refine ordinal.induction_on o _ this, introsI α r _ h,
id                                 
typ                                
2789    let s := sup.{u u} (λ a:α, inv_fun aleph_idx (ordinal.typein r a)),
id                                       └───────┘                 
src                                       └───────┘
typ                                      └───────┘                 
doc                                       └───────┘
2790    apply not_le_of_gt (lt_succ_self s),
id                                      
typ                                     
2791    have I : injective aleph_idx := aleph_idx.initial_seg.to_embedding.inj,
id                        └───────┘
src                       └───────┘
typ                       └───────┘
doc                       └───────┘
2792    simpa only [typein_enum, left_inverse_inv_fun I (succ s)] using
id                                                      └──┘ 
src                                                     └──┘
typ                                                     └──┘ 
doc                                                     └──┘
2793      le_sup.{u u} (λ a, inv_fun aleph_idx (ordinal.typein r a))
id                                 └───────┘
src                                 └───────┘
typ                                └───────┘
doc                                 └───────┘
2794        (ordinal.enum r _ (h (succ s))),
id                               └──┘ 
src                              └──┘
typ                              └──┘ 
doc                              └──┘
2795  end
st   └─┘
2796  
2797  @[simp] theorem aleph_idx.order_iso_coe :
doc    └──┘
2798    (aleph_idx.order_iso : cardinal → ordinal) = aleph_idx := rfl
id                            └┘  └┘     └──┘  
src                           └┘  └┘     └──┘  
typ                           └┘  └┘     └──┘  
doc                           └┘  └┘     └──┘  
2799  
2800  @[simp] theorem type_cardinal : @ordinal.type cardinal (<) _ = ordinal.univ.{u (u+1)} :=
id                                                 └──┘  └┘           └┘  └┘  
src                                                └──┘  └┘           └┘  └┘  
typ                                                └──┘  └┘           └┘  └┘  
doc    └──┘                                        └──┘  └┘           └┘  └┘  
2801  by rw ordinal.univ_id; exact quotient.sound ⟨aleph_idx.order_iso⟩
2802  
2803  @[simp] theorem mk_cardinal : mk cardinal = univ.{u (u+1)} :=
id                                    └──┘  └┘     
src                                   └──┘  └┘     
typ                                   └──┘  └┘     
doc    └──┘                           └──┘  └┘     
2804  by simpa only [card_type, card_univ] using congr_arg card type_cardinal
id                                                        └──┘
src                                                       └──┘
typ                                                       └──┘
doc                                                       └──┘
2805  
2806  def aleph'.order_iso := cardinal.aleph_idx.order_iso.symm
2807  
2808  /-- The `aleph'` function gives the cardinals listed by their ordinal
2809    index, and is the inverse of `aleph_idx`.
2810    `aleph' n = n`, `aleph' ω = ω`, `aleph' (ω + 1) = ℵ₁, etc. -/
2811  def aleph' : ordinal → cardinal := aleph'.order_iso
id                  └┘      └──┘  
src                 └┘      └──┘  
typ                 └┘      └──┘  
doc                 └┘      └──┘  
2812  
2813  @[simp] theorem aleph'.order_iso_coe :
doc    └──┘
2814    (aleph'.order_iso : ordinal → cardinal) = aleph' := rfl
id                         └┘  └┘     └┘ └┘
src                        └┘  └┘     └┘ └┘
typ                        └┘  └┘     └┘ └┘
doc                        └┘  └┘     └┘ └┘
2815  
2816  @[simp] theorem aleph'_lt {o₁ o₂ : ordinal.{u}} : aleph' o₁ < aleph' o₂ ↔ o₁ < o₂ :=
id                                      └┘  └┘                └┘          └┘  └┘   
src                                     └┘  └┘                               
typ                                     └┘  └┘                └┘          └┘  └┘   
doc    └──┘                             └┘  └┘
2817  aleph'.order_iso.ord'.symm
2818  
2819  @[simp] theorem aleph'_le {o₁ o₂ : ordinal.{u}} : aleph' o₁ ≤ aleph' o₂ ↔ o₁ ≤ o₂ :=
id                                        └┘                 └┘          └┘  └┘   
src                                       └┘                                
typ                                       └┘                 └┘          └┘  └┘   
doc    └──┘                               └┘  
2820  le_iff_le_iff_lt_iff_lt.2 aleph'_lt
2821  
2822  @[simp] theorem aleph'_aleph_idx (c : cardinal.{u}) : aleph' c.aleph_idx = c :=
id                                          └┘ └┘                └┘  └┘  └┘   
src                                         └┘ └┘                 └┘  └┘  └┘
typ                                         └┘ └┘                └┘  └┘  └┘   
doc    └──┘                                 └┘ └┘                 └┘  └┘  └┘
2823  cardinal.aleph_idx.order_iso.to_equiv.symm_apply_apply c
id                                                          
typ                                                         
2824  
2825  @[simp] theorem aleph_idx_aleph' (o : ordinal.{u}) : (aleph' o).aleph_idx = o :=
id                                         └┘  └─┘                 └┘  └┘      
src                                        └┘  └─┘                  └┘  └┘  
typ                                        └┘  └─┘                 └┘  └┘      
doc    └──┘                                └┘  └─┘                  └┘  └┘  
2826  cardinal.aleph_idx.order_iso.to_equiv.apply_symm_apply o
id                                                          
typ                                                         
2827  
2828  @[simp] theorem aleph'_zero : aleph' 0 = 0 :=
doc    └──┘
2829  by rw [← le_zero, ← aleph'_aleph_idx 0, aleph'_le];
2830     apply ordinal.zero_le
2831  
2832  @[simp] theorem aleph'_succ {o : ordinal.{u}} : aleph' o.succ = (aleph' o).succ :=
id                                    └──┘                 └┘              └┘
src                                   └──┘                  └┘               └┘
typ                                   └──┘                 └┘              └┘
doc    └──┘                           └──┘                  └┘               └┘
2833  le_antisymm
2834   (cardinal.aleph_idx_le.1 $
2835    by rw [aleph_idx_aleph', ordinal.succ_le, ← aleph'_lt, aleph'_aleph_idx];
2836       apply cardinal.lt_succ_self)
2837   (cardinal.succ_le.2 $ aleph'_lt.2 $ ordinal.lt_succ_self _)
2838  
2839  @[simp] theorem aleph'_nat : ∀ n : ℕ, aleph' n = n
id                                                  
src                                     
typ                                                 
doc    └──┘
2840  | 0     := aleph'_zero
2841  | (n+1) := show aleph' (ordinal.succ n) = n.succ,
id                                             └───┘
src                                             └───┘
typ                                            └───┘
2842             by rw [aleph'_succ, aleph'_nat, nat_succ]
st                                                      
2843  
2844  theorem aleph'_le_of_limit {o : ordinal.{u}} (l : o.is_limit) {c} :
id                                   └──┘             └─┘  └──┘
src                                  └──┘              └─┘  └──┘
typ                                  └──┘             └─┘  └──┘
doc                                  └──┘              └─┘  └──┘
2845    aleph' o ≤ c ↔ ∀ o' < o, aleph' o' ≤ c :=
id                                 └┘   
src                 
typ                                └┘   
2846  ⟨λ h o' h', le_trans (aleph'_le.2 $ le_of_lt h') h,
id        └┘
typ       └┘
2847   λ h, begin
2848    rw [← aleph'_aleph_idx c, aleph'_le, ordinal.limit_le l],
id                                                           
typ                                                          
2849    intros x h',
2850    rw [← aleph'_le, aleph'_aleph_idx],
2851    exact h _ h'
2852  end⟩
st   └─┘
2853  
2854  @[simp] theorem aleph'_omega : aleph' ordinal.omega = omega :=
id                                         └──────┘  └─┘   └───┘
src                                        └──────┘  └─┘   └───┘
typ                                        └──────┘  └─┘   └───┘
doc    └──┘                                └──────┘  └─┘   └───┘
2855  eq_of_forall_ge_iff $ λ c, begin
id                           
typ                          
2856    simp only [aleph'_le_of_limit omega_is_limit, ordinal.lt_omega, exists_imp_distrib, omega_le],
id                                   └────────────┘
src                                  └────────────┘
typ                                  └────────────┘
2857    exact forall_swap.trans (forall_congr $ λ n, by simp only [forall_eq, aleph'_nat]),
id                                               
typ                                              
2858  end
st   └─┘
2859  
2860  /-- aleph' and aleph_idx form an equivalence between `ordinal` and `cardinal` -/
2861  @[simp] def aleph'_equiv : ordinal ≃ cardinal :=
id                              └┘  └─┘   └─┘  └─┘
src                             └┘  └─┘   └─┘  └─┘
typ                             └┘  └─┘   └─┘  └─┘
doc    └──┘                     └┘  └─┘   └─┘  └─┘
2862  ⟨aleph', aleph_idx, aleph_idx_aleph', aleph'_aleph_idx⟩
2863  
2864  /-- The `aleph` function gives the infinite cardinals listed by their
2865    ordinal index. `aleph 0 = ω`, `aleph 1 = succ ω` is the first
2866    uncountable cardinal, and so on. -/
2867  def aleph (o : ordinal) : cardinal := aleph' (ordinal.omega + o)
id                  └┘  └─┘      └──┘             └────┘  └───┘   
src                 └┘  └─┘      └──┘             └────┘  └───┘
typ                 └┘  └─┘      └──┘             └────┘  └───┘   
doc                 └┘  └─┘      └──┘             └────┘  └───┘
2868  
2869  @[simp] theorem aleph_lt {o₁ o₂ : ordinal.{u}} : aleph o₁ < aleph o₂ ↔ o₁ < o₂ :=
id                                       └┘                └┘         └┘  └┘   
src                                      └┘                              
typ                                      └┘                └┘         └┘  └┘   
doc    └──┘                              └┘
2870  aleph'_lt.trans (ordinal.add_lt_add_iff_left _)
2871  
2872  @[simp] theorem aleph_le {o₁ o₂ : ordinal.{u}} : aleph o₁ ≤ aleph o₂ ↔ o₁ ≤ o₂ :=
id                                       └┘                └┘         └┘  └┘   
src                                      └┘                              
typ                                      └┘                └┘         └┘  └┘   
doc    └──┘                              └┘  
2873  le_iff_le_iff_lt_iff_lt.2 aleph_lt
2874  
2875  @[simp] theorem aleph_succ {o : ordinal.{u}} : aleph o.succ = (aleph o).succ :=
id                                    └┘ └┘               └┘             └┘
src                                   └┘ └┘                └┘              └┘
typ                                   └┘ └┘               └┘             └┘
doc    └──┘                           └┘ └┘                └┘              └┘
2876  by rw [aleph, ordinal.add_succ, aleph'_succ]; refl
id                                                 └──┘
src                                                └──┘
typ                                                └──┘
doc                                                └──┘
2877  
2878  @[simp] theorem aleph_zero : aleph 0 = omega :=
id                                          └───┘
src                                         └───┘
typ                                         └───┘
doc    └──┘                                 └───┘
2879  by simp only [aleph, add_zero, aleph'_omega]
id                 └───┘
src                └───┘
typ                └───┘
doc                └───┘
2880  
2881  theorem omega_le_aleph' {o : ordinal} : omega ≤ aleph' o ↔ ordinal.omega ≤ o :=
id                                └──┘      └───┘            └┘ └──┘ └┘ └┘   
src                               └──┘      └───┘             └┘ └──┘ └┘ └┘
typ                               └──┘      └───┘            └┘ └──┘ └┘ └┘   
doc                               └──┘      └───┘              └┘ └──┘ └┘ └┘
2882  by rw [← aleph'_omega, aleph'_le]
2883  
2884  theorem omega_le_aleph (o : ordinal) : omega ≤ aleph o :=
id                               └──┘      └───┘         
src                              └──┘      └───┘
typ                              └──┘      └───┘         
doc                              └──┘      └───┘
2885  by rw [aleph, omega_le_aleph']; apply ordinal.le_add_right
2886  
2887  theorem ord_aleph_is_limit (o : ordinal) : is_limit (aleph o).ord :=
id                                   └──┘        └┘           └┘
src                                  └──┘        └┘            └┘
typ                                  └──┘        └┘           └┘
doc                                  └──┘        └┘            └┘
2888  ord_is_limit $ omega_le_aleph _
2889  
2890  theorem exists_aleph {c : cardinal} : omega ≤ c ↔ ∃ o, c = aleph o :=
id                             └┘  └──┘      └─┘                  
src                            └┘  └──┘      └─┘     
typ                            └┘  └──┘      └─┘                  
doc                            └┘  └──┘      └─┘
2891  ⟨λ h, ⟨aleph_idx c - ordinal.omega,
id                       └───┘ └────┘
src                       └───┘ └────┘
typ                      └───┘ └────┘
doc                       └───┘ └────┘
2892    by rw [aleph, ordinal.add_sub_cancel_of_le, aleph'_aleph_idx];
2893       rwa [← omega_le_aleph', aleph'_aleph_idx]⟩,
2894   λ ⟨o, e⟩, e.symm ▸ omega_le_aleph _⟩
2895  
2896  theorem aleph'_is_normal : is_normal (ord ∘ aleph') :=
2897  ⟨λ o, ord_lt_ord.2 $ aleph'_lt.2 $ ordinal.lt_succ_self _,
id      
typ     
2898   λ o l a, by simp only [ord_le, aleph'_le_of_limit l]⟩
id                                                   
typ                                                  
2899  
2900  theorem aleph_is_normal : is_normal (ord ∘ aleph) :=
2901  aleph'_is_normal.trans $ add_is_normal ordinal.omega
id                                          └────┘  └───┘
src                                         └────┘  └───┘
typ                                         └────┘  └───┘
doc                                         └────┘  └───┘
2902  
2903  /- properties of mul -/
2904  
2905  theorem mul_eq_self {c : cardinal} (h : omega ≤ c) : c * c = c :=
id                             └┘ └┘         └──┘              
src                            └┘ └┘         └──┘
typ                            └┘ └┘         └──┘              
doc                            └┘ └┘         └──┘
2906  begin
2907    refine le_antisymm _
2908      (by simpa only [mul_one] using mul_le_mul_left c (le_trans (le_of_lt one_lt_omega) h)),
id                                                      
typ                                                     
2909    refine acc.rec_on (cardinal.wf.apply c) (λ c _,
id                                               
typ                                              
2910      quotient.induction_on c $ λ α IH ol, _) h,
id                                   
typ                                  
2911    rcases ord_eq α with ⟨r, wo, e⟩, resetI,
id                   
typ                  
2912    let := decidable_linear_order_of_STO' r,
id                                           
typ                                          
2913    have : is_well_order α (<) := wo,
id                                  └┘
typ                                 └┘
2914    let g : α × α → α := λ p, max p.1 p.2,
id                           
typ                          
2915    let f : α × α ↪ ordinal × (α × α) :=
id                     └─────┘        
src                    └─────┘
typ                    └─────┘        
doc                    └─────┘
2916      ⟨λ p:α×α, (typein (<) (g p), p), λ p q, congr_arg prod.snd⟩,
id                                         
typ                                        
2917    let s := f ⁻¹'o (prod.lex (<) (prod.lex (<) (<))),
2918    have : is_well_order _ s := (order_embedding.preimage _ _).is_well_order,
2919    suffices : type s ≤ type r, {exact card_le_card this},
id                              
typ                             
st                                                         └┘
2920    refine le_of_forall_lt (λ o h, _),
id                               
typ                              
2921    rcases typein_surj s h with ⟨p, rfl⟩,
2922    rw [← e, lt_ord],
2923    refine lt_of_le_of_lt (_ : _ ≤ card (typein (<) (g p)).succ * card (typein (<) (g p)).succ) _,
2924    { have : {q|s q p} ⊆ (insert (g p) {x | x < (g p)}).prod (insert (g p) {x | x < (g p)}),
id                                                                           
typ                                                                          
2925      { intros q h,
2926        simp only [s, embedding.coe_fn_mk, order.preimage, typein_lt_typein, prod.lex_def, typein_inj] at h,
2927        exact max_le_iff.1 (le_iff_lt_or_eq.2 $ h.imp_right and.left) },
st                                                                       └┘
2928      suffices H : (insert (g p) {x | r x (g p)} : set α) ≃ ({x | r x (g p)} ⊕ punit),
id                                                   └─┘                     └───┘
src                                                   └─┘                       └───┘
typ                                                  └─┘                     └───┘
doc                                                          
2929      { exact ⟨(set.embedding_of_subset this).trans
2930          ((equiv.set.prod _ _).trans (H.prod_congr H)).to_embedding⟩ },
st                                                                       └┘
2931      refine (equiv.set.insert _).trans
2932        ((equiv.refl _).sum_congr punit_equiv_punit),
2933      apply @irrefl _ r },
id                       
typ                      
st                         └┘
2934    cases lt_or_ge (card (typein (<) (g p)).succ) omega with qo qo,
id                     └──┘                        └───┘
src                    └──┘                          └───┘
typ                    └──┘                        └───┘
doc                    └──┘                          └───┘
2935    { exact lt_of_lt_of_le (mul_lt_omega qo qo) ol },
st                                                    └┘
2936    { suffices, {exact lt_of_le_of_lt (IH _ this qo) this},
st                                                          └┘
2937      rw ← lt_ord, apply (ord_is_limit ol).2,
2938      rw [mk_def, e], apply typein_lt_type }
st                                            └─
2939  end
st   ──┘
2940  
2941  end using_ordinals
2942  
2943  theorem mul_eq_max {a b : cardinal} (ha : omega ≤ a) (hb : omega ≤ b) : a * b = max a b :=
id                             └┘  └┘          └───┘           └┘ └┘                  
src                            └┘  └┘          └───┘            └┘ └┘
typ                            └┘  └┘          └───┘           └┘ └┘                  
doc                            └┘  └┘          └───┘            └┘ └┘
2944  le_antisymm
2945    (mul_eq_self (le_trans ha (le_max_left a b)) ▸
id                                             
typ                                            
2946      mul_le_mul (le_max_left _ _) (le_max_right _ _)) $
2947  max_le
2948    (by simpa only [mul_one] using mul_le_mul_left a (le_trans (le_of_lt one_lt_omega) hb))
id                                                    
typ                                                   
2949    (by simpa only [one_mul] using mul_le_mul_right b (le_trans (le_of_lt one_lt_omega) ha))
id                                                     
typ                                                    
2950  
2951  theorem mul_lt_of_lt {a b c : cardinal} (hc : omega ≤ c)
id                                 └┘  └┘          └───┘   
src                                └┘  └┘          └───┘
typ                                └┘  └┘          └───┘   
doc                                └┘  └┘          └───┘
2952    (h1 : a < c) (h2 : b < c) : a * b < c :=
id                                   
typ                                  
2953  lt_of_le_of_lt (mul_le_mul (le_max_left a b) (le_max_right a b)) $
id                                                             
typ                                                            
2954  (lt_or_le (max a b) omega).elim
id                     └─┘
src                      └─┘
typ                    └─┘
doc                      └─┘
2955    (λ h, lt_of_lt_of_le (mul_lt_omega h h) hc)
2956    (λ h, by rw mul_eq_self h; exact max_lt h1 h2)
2957  
2958  lemma mul_le_max_of_omega_le_left {a b : cardinal} (h : omega ≤ a) : a * b ≤ max a b :=
id                                            └┘  └┘         └───┘                  
src                                           └┘  └┘         └───┘
typ                                           └┘  └┘         └───┘                  
doc                                           └┘  └┘         └───┘
2959  begin
2960    convert mul_le_mul (le_max_left a b) (le_max_right a b), rw [mul_eq_self],
id                                                         
typ                                                        
2961    refine le_trans h (le_max_left a b)
id                                     
typ                                    
2962  end
st   └─┘
2963  
2964  lemma mul_eq_max_of_omega_le_left {a b : cardinal} (h : omega ≤ a) (h' : b ≠ 0) : a * b = max a b :=
id                                            └┘  └┘         └───┘                              
src                                           └┘  └┘         └───┘
typ                                           └┘  └┘         └───┘                              
doc                                           └┘  └┘         └───┘
2965  begin
2966    apply le_antisymm, apply mul_le_max_of_omega_le_left h,
2967    cases le_or_gt omega b with hb hb, rw [mul_eq_max h hb],
id                    └───┘ 
src                   └───┘
typ                   └───┘ 
doc                   └───┘
st                                                           
2968    have : b ≤ a, exact le_trans (le_of_lt hb) h,
id               
typ              
2969    rw [max_eq_left this], convert mul_le_mul_left _ (one_le_iff_ne_zero.mpr h'), rw [mul_one],
st                                                                                              
2970  end
st   └─┘
2971  
2972  lemma mul_eq_left {a b : cardinal} (ha : omega ≤ a) (hb : b ≤ a) (hb' : b ≠ 0) : a * b = a :=
id                            └┘  └┘          └───┘                                     
src                           └┘  └┘          └───┘
typ                           └┘  └┘          └───┘                                     
doc                           └┘  └┘          └───┘
2973  by { rw [mul_eq_max_of_omega_le_left ha hb', max_eq_left hb] }
st                                                                └┘
2974  
2975  lemma mul_eq_right {a b : cardinal} (hb : omega ≤ b) (ha : a ≤ b) (ha' : a ≠ 0) : a * b = b :=
id                             └┘  └┘          └───┘                                     
src                            └┘  └┘          └───┘
typ                            └┘  └┘          └───┘                                     
doc                            └┘  └┘          └───┘
2976  by { rw [mul_comm, mul_eq_left hb ha ha'] }
st                                             └┘
2977  
2978  lemma le_mul_left {a b : cardinal} (h : b ≠ 0) : a ≤ b * a :=
id                            └┘  └┘                       
src                           └┘  └┘
typ                           └┘  └┘                       
doc                           └┘  └┘
2979  by { convert mul_le_mul_right _ (one_le_iff_ne_zero.mpr h), rw [one_mul] }
st                                                                           └┘
2980  
2981  lemma le_mul_right {a b : cardinal} (h : b ≠ 0) : a ≤ a * b :=
id                             └┘  └┘                       
src                            └┘  └┘
typ                            └┘  └┘                       
doc                            └┘  └┘
2982  by { rw [mul_comm], exact le_mul_left h }
st                                           └┘
2983  
2984  lemma mul_eq_left_iff {a b : cardinal} : a * b = a ↔ ((max omega b ≤ a ∧ b ≠ 0) ∨ b = 1 ∨ a = 0) :=
id                                └┘  └┘                    └───┘                    
src                               └┘  └┘                       └───┘                       
typ                               └┘  └┘                    └───┘                    
doc                               └┘  └┘                        └───┘
2985  begin
2986    rw [max_le_iff], split,
2987    { intro h,
2988      cases (le_or_lt omega a) with ha ha,
id                       └───┘ 
src                      └───┘
typ                      └───┘ 
doc                      └───┘
2989      { have : a ≠ 0, { rintro rfl, exact not_lt_of_le ha omega_pos },
id                
typ               
st                                                                     └┘
2990        left, use ha,
2991        { rw [← not_lt], intro hb, apply ne_of_gt _ h, refine lt_of_lt_of_le hb (le_mul_left this) },
st                                                                                                    └┘
2992        { rintro rfl, apply this, rw [_root_.mul_zero] at h, subst h }},
st                                                                      └─┘
2993      right, by_cases h2a : a = 0, { right, exact h2a },
id                             
typ                            
st                                                       └┘
2994      have hb : b ≠ 0, { rintro rfl, apply h2a, rw [mul_zero] at h, subst h },
id                 
typ                
st                                                                             └┘
2995      left, rw [← h, mul_lt_omega_iff, lt_omega, lt_omega] at ha,
2996      rcases ha with rfl|rfl|⟨⟨n, rfl⟩, ⟨m, rfl⟩⟩, contradiction, contradiction,
2997      rw [← ne] at h2a, rw [← one_le_iff_ne_zero] at h2a hb, norm_cast at h2a hb h ⊢,
2998      apply le_antisymm _ hb, rw [← not_lt], intro h2b,
2999      apply ne_of_gt _ h, rw [gt], conv_lhs { rw [← mul_one n] },
id                                                             
typ                                                            
3000      rwa [mul_lt_mul_left], apply nat.lt_of_succ_le h2a },
st                                                          └┘
3001    { rintro (⟨⟨ha, hab⟩, hb⟩|rfl|rfl),
3002      { rw [mul_eq_max_of_omega_le_left ha hb, max_eq_left hab] },
st                                                                └┘
3003      all_goals {simp}}
st                      └──
3004  end
st   ──┘
3005  
3006  /- properties of add -/
3007  
3008  theorem add_eq_self {c : cardinal} (h : omega ≤ c) : c + c = c :=
id                            └──┘  └┘       └──┘              
src                           └──┘  └┘       └──┘
typ                           └──┘  └┘       └──┘              
doc                           └──┘  └┘       └──┘
3009  le_antisymm
3010    (by simpa only [nat.cast_bit0, nat.cast_one, mul_eq_self h, two_mul] using
3011       mul_le_mul_right c (le_trans (le_of_lt $ nat_lt_omega 2) h))
id                         
typ                        
3012    (le_add_left c c)
id                   
typ                  
3013  
3014  theorem add_eq_max {a b : cardinal} (ha : omega ≤ a) : a + b = max a b :=
id                             └┘  └┘          └───┘                  
src                            └┘  └┘          └───┘
typ                            └┘  └┘          └───┘                  
doc                            └┘  └┘          └───┘
3015  le_antisymm
3016    (add_eq_self (le_trans ha (le_max_left a b)) ▸
id                                             
typ                                            
3017      add_le_add (le_max_left _ _) (le_max_right _ _)) $
3018  max_le (le_add_right _ _) (le_add_left _ _)
3019  
3020  theorem add_lt_of_lt {a b c : cardinal} (hc : omega ≤ c)
id                                   └┘  └┘          └─┘   
src                                  └┘  └┘          └─┘
typ                                  └┘  └┘          └─┘   
doc                                  └┘  └┘          └─┘
3021    (h1 : a < c) (h2 : b < c) : a + b < c :=
id                                   
typ                                  
3022  lt_of_le_of_lt (add_le_add (le_max_left a b) (le_max_right a b)) $
id                                                             
typ                                                            
3023  (lt_or_le (max a b) omega).elim
id                     └─┘
src                      └─┘
typ                    └─┘
doc                      └─┘
3024    (λ h, lt_of_lt_of_le (add_lt_omega h h) hc)
3025    (λ h, by rw add_eq_self h; exact max_lt h1 h2)
3026  
3027  lemma eq_of_add_eq_of_omega_le {a b c : cardinal} (h : a + b = c) (ha : a < c) (hc : omega ≤ c) :
id                                           └┘  └┘                                  └──┘    
src                                          └┘  └┘                                       └──┘
typ                                          └┘  └┘                                  └──┘    
doc                                          └┘  └┘                                       └──┘
3028    b = c :=
id         
typ        
3029  begin
3030    apply le_antisymm,
3031    { rw [← h], apply cardinal.le_add_left },
st                                            └┘
3032    rw[← not_lt], intro hb,
3033    have : a + b < c := add_lt_of_lt hc ha hb,
id                  
typ                 
3034    simpa [h, lt_irrefl] using this
3035  end
st   └─┘
3036  
3037  lemma add_eq_left {a b : cardinal} (ha : omega ≤ a) (hb : b ≤ a) : a + b = a :=
id                            └┘  └┘          └───┘                        
src                           └┘  └┘          └───┘
typ                           └┘  └┘          └───┘                        
doc                           └┘  └┘          └───┘
3038  by { rw [add_eq_max ha, max_eq_left hb] }
st                                           └┘
3039  
3040  lemma add_eq_right {a b : cardinal} (hb : omega ≤ b) (ha : a ≤ b) : a + b = b :=
id                             └┘  └┘          └───┘                        
src                            └┘  └┘          └───┘
typ                            └┘  └┘          └───┘                        
doc                            └┘  └┘          └───┘
3041  by { rw [add_comm, add_eq_left hb ha] }
st                                         └┘
3042  
3043  lemma add_eq_left_iff {a b : cardinal} : a + b = a ↔ (max omega b ≤ a ∨ b = 0) :=
id                                └┘  └┘                   └───┘      
src                               └┘  └┘                      └───┘       
typ                               └┘  └┘                   └───┘      
doc                               └┘  └┘                       └───┘
3044  begin
3045    rw [max_le_iff], split,
3046    { intro h, cases (le_or_lt omega a) with ha ha,
id                                └───┘ 
src                               └───┘
typ                               └───┘ 
doc                               └───┘
3047      { left, use ha, rw [← not_lt], intro hb, apply ne_of_gt _ h,
3048        exact lt_of_lt_of_le hb (le_add_left b a) },
id                                               
typ                                              
st                                                   └┘
3049      right, rw [← h, add_lt_omega_iff, lt_omega, lt_omega] at ha,
3050      rcases ha with ⟨⟨n, rfl⟩, ⟨m, rfl⟩⟩, norm_cast at h ⊢,
3051      rw [← add_left_inj, h, add_zero] },
st                                       └┘
3052    { rintro (⟨h1, h2⟩|h3), rw [add_eq_max h1, max_eq_left h2], rw [h3, add_zero] }
st                                                                                  └─
3053  end
st   ──┘
3054  
3055  lemma add_eq_right_iff {a b : cardinal} : a + b = b ↔ (max omega a ≤ b ∨ a = 0) :=
id                                 └┘  └┘                   └───┘      
src                                └┘  └┘                      └───┘       
typ                                └┘  └┘                   └───┘      
doc                                └┘  └┘                       └───┘
3056  by { rw [add_comm, add_eq_left_iff] }
st                                      └┘
3057  
3058  lemma add_one_eq {a : cardinal} (ha : omega ≤ a) : a + 1 = a :=
id                         └──┘  └┘        └──┘               
src                        └──┘  └┘        └──┘
typ                        └──┘  └┘        └──┘               
doc                        └──┘  └┘        └──┘
3059  have 1 ≤ a, from le_trans (le_of_lt one_lt_omega) ha,
id            
typ           
3060  add_eq_left ha this
3061  
3062  protected lemma eq_of_add_eq_add_left {a b c : cardinal} (h : a + b = a + c) (ha : a < omega) :
id                                                    └┘  └┘                            └───┘
src                                                   └┘  └┘                                └───┘
typ                                                   └┘  └┘                            └───┘
doc                                                   └┘  └┘                                └───┘
3063    b = c :=
id         
typ        
3064  begin
3065    cases le_or_lt omega b with hb hb,
3066    { have : a < b := lt_of_lt_of_le ha hb,
id                 
typ                
3067      rw [add_eq_right hb (le_of_lt this), eq_comm] at h,
3068      rw [eq_of_add_eq_of_omega_le h this hb] },
st                                              └┘
3069    { have hc : c < omega,
id                    └───┘
src                    └───┘
typ                   └───┘
doc                    └───┘
3070      { rw [← not_le], intro hc,
3071        apply lt_irrefl omega, apply lt_of_le_of_lt (le_trans hc (le_add_left _ a)),
id                         └───┘                                                   
src                        └───┘
typ                        └───┘                                                   
doc                        └───┘
3072        rw [← h], apply add_lt_omega ha hb },
st                                            └┘
3073      rw [lt_omega] at *,
3074      rcases ha with ⟨n, rfl⟩, rcases hb with ⟨m, rfl⟩, rcases hc with ⟨k, rfl⟩,
3075      norm_cast at h ⊢, apply eq_of_add_eq_add_left h }
st                                                       └─
3076  end
st   ──┘
3077  
3078  protected lemma eq_of_add_eq_add_right {a b c : cardinal} (h : a + b = c + b) (hb : b < omega) :
id                                                     └┘  └┘                            └───┘
src                                                    └┘  └┘                                └───┘
typ                                                    └┘  └┘                            └───┘
doc                                                    └┘  └┘                                └───┘
3079    a = c :=
id         
typ        
3080  by { rw [add_comm a b, add_comm c b] at h, exact cardinal.eq_of_add_eq_add_left h hb }
st                                                                                        └┘
3081  
3082  /- properties about power -/
3083  
3084  theorem pow_le {κ μ : cardinal.{u}} (H1 : omega ≤ κ) (H2 : μ < omega) : κ ^ μ ≤ κ :=
id                         └┘  └┘              └───┘              └───┘          
src                        └┘  └┘              └───┘                └───┘
typ                        └┘  └┘              └───┘              └───┘          
doc                        └┘  └┘              └───┘                └───┘
3085  let ⟨n, H3⟩ := lt_omega.1 H2 in
id        
typ       
3086  H3.symm ▸ (quotient.induction_on κ (λ α H1, nat.rec_on n
id                                        
typ                                       
3087    (le_of_lt $ lt_of_lt_of_le (by rw [nat.cast_zero, power_zero];
3088      from one_lt_omega) H1)
3089    (λ n ih, trans_rel_left _
id        
typ       
3090      (by rw [nat.cast_succ, power_add, power_one];
3091        from mul_le_mul_right _ ih)
3092      (mul_eq_self H1))) H1)
3093  
3094  lemma power_self_eq {c : cardinal} (h : omega ≤ c) : c ^ c = 2 ^ c :=
id                            └──┘  └┘       └──┘                  
src                           └──┘  └┘       └──┘
typ                           └──┘  └┘       └──┘                  
doc                           └──┘  └┘       └──┘
3095  begin
3096    apply le_antisymm,
3097    { apply le_trans (power_le_power_right $ le_of_lt $ cantor c), rw [power_mul, mul_eq_self h] },
id                                                                
typ                                                               
st                                                                                                 └┘
3098    { convert power_le_power_right (le_trans (le_of_lt $ nat_lt_omega 2) h), apply nat.cast_two.symm }
st                                                                                                      └─
3099  end
st   ──┘
3100  
3101  lemma power_nat_le {c : cardinal.{u}} {n : ℕ} (h  : omega ≤ c) : c ^ (n : cardinal.{u}) ≤ c :=
id                           └──┘  └┘                   └┘                └┘  └──┘        
src                          └──┘  └┘                   └┘                   └┘  └──┘
typ                          └──┘  └┘                   └┘                └┘  └──┘        
doc                          └──┘  └┘                    └┘                   └┘  └──┘
3102  pow_le h (nat_lt_omega n)
id                          
typ                         
3103  
3104  lemma powerlt_omega {c : cardinal} (h : omega ≤ c) : c ^< omega = c :=
id                              └──┘         └─┘           └───┘   
src                             └──┘         └─┘             └───┘
typ                             └──┘         └─┘           └───┘   
doc                             └──┘         └─┘             └───┘
3105  begin
3106    apply le_antisymm,
3107    { rw [powerlt_le], intro c', rw [lt_omega], rintro ⟨n, rfl⟩, apply power_nat_le h },
st                                                                                       └┘
3108    convert le_powerlt one_lt_omega, rw [power_one]
st                                                   
3109  end
st   └─┘
3110  lemma powerlt_omega_le (c : cardinal) : c ^< omega ≤ max c omega :=
id                               └──┘  └┘        └───┘        └───┘
src                              └──┘  └┘         └───┘         └───┘
typ                              └──┘  └┘        └───┘        └───┘
doc                              └──┘  └┘         └───┘         └───┘
3111  begin
3112    cases le_or_gt omega c,
3113    { rw [powerlt_omega h], apply le_max_left },
st                                               └┘
3114    rw [powerlt_le], intros c' hc',
3115    refine le_trans (le_of_lt $ power_lt_omega h hc') (le_max_right _ _)
3116  end
st   └─┘
3117  
3118  /- compute cardinality of various types -/
3119  
3120  theorem mk_list_eq_mk {α : Type u} (H1 : omega ≤ mk α) : mk (list α) = mk α :=
id                                            └───┘             └┘         
src                                           └───┘             └┘        
typ                                           └───┘             └┘         
doc                                           └───┘                       
3121  eq.symm $ le_antisymm ⟨⟨λ x, [x], λ x y H, (list.cons.inj H).1⟩⟩ $
id                                      
typ                                     
3122  calc  mk (list α)
id                  
typ                 
3123      = sum (λ n : ℕ, mk α ^ (n : cardinal.{u})) : mk_list_eq_sum_pow α
id                                 └┘                              
src                                  └┘  
typ                                └┘                              
doc                                   └┘  
3124  ... ≤ sum (λ n : ℕ, mk α) : sum_le_sum _ _ $ λ n, pow_le H1 $ nat_lt_omega n
id                                                                           
src                   
typ                                                                          
3125  ... = sum (λ n : ulift.{u} ℕ, mk α) : quotient.sound
id                                   
src                             
typ                                  
3126    ⟨@sigma_congr_left _ _ (λ _, quotient.out (mk α)) equiv.ulift.symm⟩
id                                                   
typ                                                  
3127  ... = omega * mk α : sum_const _ _
id         └──┘       
src        └──┘
typ        └──┘       
doc        └──┘
3128  ... = max (omega) (mk α) : mul_eq_max (le_refl _) H1
id              └┘        
src             └┘  
typ             └┘        
doc             └┘  
3129  ... = mk α : max_eq_right H1
id           
src        
typ          
doc        
3130  
3131  lemma mk_bounded_set_le_of_omega_le (α : Type u) (c : cardinal) (hα : omega ≤ mk α) :
id                                                         └┘  └──┘          └─┘     
src                                                        └┘  └──┘          └─┘   
typ                                                        └┘  └──┘          └─┘     
doc                                                        └┘  └──┘          └─┘   
3132    mk {t : set α // mk t ≤ c} ≤ mk α ^ c :=
id                                     
src     
typ                                    
doc     
3133  begin
3134    refine le_trans _ (by rw [←add_one_eq hα]), refine quotient.induction_on c _, clear c, intro β,
id                                                                              
typ                                                                             
st                                             
3135    fapply mk_le_of_surjective,
3136    { intro f, use sum.inl ⁻¹' range f,
3137      refine le_trans (mk_preimage_of_injective _ _ (λ x y, sum.inl.inj)) _,
id                                                         
typ                                                        
3138      apply mk_range_le },
st                         └┘
3139    rintro ⟨s, ⟨g⟩⟩,
3140    use λ y, if h : ∃(x : s), g x = y then sum.inl (classical.some h).val else sum.inr ⟨⟩,
id                                                                                       
src                                                                                       
typ                                                                                      
3141    apply subtype.eq, ext,
3142    split,
3143    { rintro ⟨y, h⟩, dsimp only at h, by_cases h' : ∃ (z : s), g z = y,
id                                                                      
typ                                                                     
3144      { rw [dif_pos h'] at h, cases sum.inl.inj h, exact (classical.some h').2 },
st                                                                                └┘
3145      { rw [dif_neg h'] at h, cases h }},
st                                       └─┘
3146    { intro h, have : ∃(z : s), g z = g ⟨x, h⟩, exact ⟨⟨x, h⟩, rfl⟩,
id                                                        
typ                                                       
3147      use g ⟨x, h⟩, dsimp only, rw [dif_pos this], congr',
id              
typ             
3148      suffices : classical.some this = ⟨x, h⟩, exact congr_arg subtype.val this,
id                                         
typ                                        
3149      apply g.2, exact classical.some_spec this }
st                                                 └─
3150  end
st   ──┘
3151  
3152  lemma mk_bounded_set_le (α : Type u) (c : cardinal) :
id                                             └┘  └──┘
src                                            └┘  └──┘
typ                                            └┘  └──┘
doc                                            └┘  └──┘
3153    mk {t : set α // mk t ≤ c} ≤ max (mk α) omega ^ c :=
id                                          └──┘    
src                                            └──┘
typ                                         └──┘    
doc                                            └──┘
3154  begin
3155    transitivity mk {t : set (ulift.{u} nat ⊕ α) // mk t ≤ c},
id                                         └─┘        └┘     
src                                        └─┘         └┘
typ                                        └─┘        └┘     
doc                                                    └┘
3156    { refine ⟨embedding.subtype_map _ _⟩, apply embedding.image,
3157      use sum.inr, apply sum.inr.inj, intros s hs, exact le_trans mk_image_le hs },
st                                                                                  └┘
3158    refine le_trans
3159      (mk_bounded_set_le_of_omega_le (ulift.{u} nat ⊕ α) c (le_add_right omega (mk α))) _,
id                                       └───┘     └─┘                     └───┘  └┘ 
src                                      └───┘     └─┘                      └───┘  └┘
typ                                      └───┘     └─┘                     └───┘  └┘ 
doc                                      └───┘                              └───┘  └┘
3160    rw [max_comm, ←add_eq_max]; refl
id                                 └──┘
src                                └──┘
typ                                └──┘
doc                                └──┘
3161  end
st   └─┘
3162  
3163  lemma mk_bounded_subset_le {α : Type u} (s : set α) (c : cardinal.{u}) :
id                                                           └──┘  └┘
src                                                          └──┘  └┘
typ                                                          └──┘  └┘
doc                                                           └──┘  └┘
3164    mk {t : set α // t ⊆ s ∧ mk t ≤ c} ≤ max (mk s) omega ^ c :=
id                                              └┘ └┘   
src                                                   └┘ └┘
typ                                             └┘ └┘   
doc                                                    └┘ └┘
3165  begin
3166    refine le_trans _ (mk_bounded_set_le s c),
3167    refine ⟨embedding.cod_restrict _ _ _⟩,
3168    use λ t, subtype.val ⁻¹' t.1,
3169    { rintros ⟨t, ht1, ht2⟩ ⟨t', h1t', h2t'⟩ h, apply subtype.eq, dsimp only at h ⊢,
3170      refine (preimage_eq_preimage' _ _).1 h; rw [subtype.range_val]; assumption },
id                                                                       └────────┘
src                                                                      └────────┘
typ                                                                      └────────┘
doc                                                                      └────────┘
st                                                                                  └┘
3171    rintro ⟨t, h1t, h2t⟩, exact le_trans (mk_preimage_of_injective _ _ subtype.val_injective) h2t
3172  end
st   └─┘
3173  
3174  /- compl -/
3175  
3176  lemma mk_compl_of_omega_le {α : Type*} (s : set α) (h : omega ≤ #α) (h2 : #s < #α) :
id                                                         └───┘                
src                                                         └───┘                 
typ                                                        └───┘                
doc                                                          └───┘                 
3177    #(-s : set α) = #α :=
id                   
src                   
typ                  
doc                    
3178  by { refine eq_of_add_eq_of_omega_le _ h2 h, exact mk_sum_compl s }
id                                                                   
typ                                                                  
st                                                                     └┘
3179  
3180  lemma mk_compl_finset_of_omega_le {α : Type*} (s : finset α) (h : omega ≤ #α) :
id                                                        └┘          └───┘   
src                                                       └┘           └───┘   
typ                                                       └┘          └───┘   
doc                                                       └┘           └───┘   
3181    #(-s.to_set : set α) = #α :=
id                   └┘      
src                  └┘       
typ                  └┘      
doc                           
3182  by { apply mk_compl_of_omega_le _ h, exact lt_of_lt_of_le (finset_card_lt_omega s) h }
id                                                                                   
typ                                                                                  
st                                                                                        └┘
3183  
3184  lemma mk_compl_eq_mk_compl_infinite {α : Type*} {s t : set α} (h : omega ≤ #α) (hs : #s < #α)
id                                                                     └───┘                
src                                                                     └───┘                 
typ                                                                    └───┘                
doc                                                                     └───┘                 
3185    (ht : #t < #α) : #(-s : set α) = #(-t : set α) :=
id                                         
src                                           
typ                                        
doc                                    
3186  by { rw [mk_compl_of_omega_le s h hs, mk_compl_of_omega_le t h ht] }
st                                                                     └┘
3187  
3188  lemma mk_compl_eq_mk_compl_finite_lift {α : Type u} {β : Type v} {s : set α} {t : set β}
id                                                                                   └┘  
src                                                                                   └┘
typ                                                                                  └┘  
3189    (hα : #α < omega) (h1 : lift.{u (max v w)} (#α) = lift.{v (max u w)} (#β))
id              └─┘                                                     
src              └─┘                                                      
typ             └─┘                                                     
doc              └─┘                                                      
3190    (h2 : lift.{u (max v w)} (#s) = lift.{v (max u w)} (#t)) :
id                                                        
src                              
typ                                                       
doc                              
3191    lift.{u (max v w)} (#(-s : set α)) = lift.{v (max u w)} (#(-t : set β)) :=
id                                                                     
src                                                                     
typ                                                                    
3192  begin
3193    have hα' := hα, have h1' := h1,
3194    rw [← mk_sum_compl s, ← mk_sum_compl t] at h1,
id                                         
typ                                        
3195    rw [← mk_sum_compl s, add_lt_omega_iff] at hα,
id                        
typ                       
3196    lift #s to ℕ using hα.1 with n hn,
id               
src               
typ              
3197    lift #(- s : set α) to ℕ using hα.2 with m hm,
id                 └─┘      
src                 └─┘       
typ                └─┘      
3198    have : #(- t : set β) < omega,
id                   └─┘     └───┘
src                   └─┘      └───┘
typ                  └─┘     └───┘
doc                            └───┘
3199    { refine lt_of_le_of_lt (mk_subtype_le _) _,
3200      rw [← lift_lt, lift_omega, ← h1', ← lift_omega.{u (max v w)}, lift_lt], exact hα' },
st                                                                                         └┘
3201    lift #(- t : set β) to ℕ using this with k hk,
id                 └─┘      
src                 └─┘       
typ                └─┘      
3202    simp [nat_eq_lift_eq_iff] at h2, rw [nat_eq_lift_eq_iff.{v (max u w)}] at h2,
3203    simp [h2.symm] at h1 ⊢, norm_cast at h1, simp at h1, exact h1
id                                                                └┘
typ                                                               └┘
3204  end
st   └─┘
3205  
3206  lemma mk_compl_eq_mk_compl_finite {α β : Type u} {s : set α} {t : set β}
id                                                                   └┘  
src                                                                   └┘
typ                                                                  └┘  
3207    (hα : #α < omega) (h1 : #α = #β) (h : #s = #t) : #(-s : set α) = #(-t : set β) :=
id               └───┘                                                 
src               └───┘                                                     
typ              └───┘                                                 
doc               └───┘                                              
3208  by { rw [← lift_inj], apply mk_compl_eq_mk_compl_finite_lift hα; rw [lift_inj]; assumption }
id                                                                                   └────────┘
src                                                                                  └────────┘
typ                                                                                  └────────┘
doc                                                                                  └────────┘
st                                                                                              └┘
3209  
3210  lemma mk_compl_eq_mk_compl_finite_same {α : Type*} {s t : set α} (hα : #α < omega)
id                                                                            └─┘ 
src                                                                             └─┘ 
typ                                                                           └─┘ 
doc                                                                             └─┘ 
3211    (h : #s = #t) : #(-s : set α) = #(-t : set α) :=
id                                        
src                                          
typ                                       
doc                                   
3212  mk_compl_eq_mk_compl_finite hα rfl h
3213  
3214  /- extend an injection to an equiv -/
3215  
3216  theorem extend_function {α β : Type*} {s : set α} (f : s ↪ β)
id                                                           
src                                               
typ                                                          
3217    (h : nonempty ((-s : set α) ≃ (- range f : set β))) :
id                          └┘                     
src                          └┘                    
typ                         └┘                     
3218    ∃ (g : α ≃ β), ∀ x : s, g x = f x :=
id               
typ              
3219  begin
3220    intros, have := h, cases this with g,
3221    let h : α ≃ β := (set.sum_compl (s : set α)).symm.trans
id                                       └─┘ 
src                                         └─┘
typ                                      └─┘ 
3222      ((sum_congr (equiv.set.range f f.2) g).trans
3223      (set.sum_compl (range f))),
3224    refine ⟨h, _⟩, rintro ⟨x, hx⟩, simp [set.sum_compl_symm_apply_of_mem, hx, equiv.symm]
id             
typ            
3225  end
st   └─┘
3226  
3227  theorem extend_function_finite {α β : Type*} {s : set α} (f : s ↪ β)
id                                                                  
src                                                      
typ                                                                 
3228    (hs : #α < omega) (h : nonempty (α ≃ β)) : ∃ (g : α ≃ β), ∀ x : s, g x = f x :=
id              └─┘                                    
src              └─┘ 
typ             └─┘                                    
doc              └─┘ 
3229  begin
3230    apply extend_function f,
3231    have := h, cases this with g,
3232    rw [← lift_mk_eq] at h,
3233    rw [←lift_mk_eq, mk_compl_eq_mk_compl_finite_lift hs h],
3234    rw [mk_range_eq_lift], exact f.2
3235  end
st   └─┘
3236  
3237  theorem extend_function_of_lt {α β : Type*} {s : set α} (f : s ↪ β) (hs : #s < #α)
id                                                                            
src                                                                               
typ                                                                           
doc                                                                                
3238    (h : nonempty (α ≃ β)) : ∃ (g : α ≃ β), ∀ x : s, g x = f x :=
id                                      
typ                                     
3239  begin
3240    cases (le_or_lt omega (#α)) with hα hα,
id                     └───┘  
src                    └───┘  
typ                    └───┘  
doc                    └───┘  
3241    { apply extend_function f, have := h, cases this with g, rw [← lift_mk_eq] at h,
3242      cases cardinal.eq.mp (mk_compl_of_omega_le s hα hs) with g2,
id                                                  
typ                                                 
3243      cases cardinal.eq.mp (mk_compl_of_omega_le (range f) _ _) with g3,
3244      { constructor, exact g2.trans (g.trans g3.symm) },
st                                                       └┘
3245      { rw [← lift_le, ← h], refine le_trans _ (lift_le.mpr hα), simp },
st                                                                       └┘
3246      rwa [← lift_lt, ← h, mk_range_eq_lift, lift_lt], exact f.2 },
st                                                                  └┘
3247    { exact extend_function_finite f hα h }
st                                           └─
3248  end
st   ──┘
3249  
3250  end cardinal